What is the normal form of this lambda calculus and are there any free variables? - lambda-calculus

I am trying to learn lambda calculus, but I am having a hard time doing it. So if anyone would explain a little bit, I would greatly appreciate it!
(λj.λx.f(j x)) (λy.f y)

There is one free variable, f. j, x, and y are all bound by an abstraction.
There are two ways you can reach normal form. Either perform two beta reductions
(λj.λx.f(j x)) (λy.f y) == (λx.f((λy.f y) x)) apply (λj.λx.f(j x)) to (λy.f y)
== (λx.f(f x)) apply (λy.f y) to x
or perform an eta reduction followed by a beta reduction.
(λj.λx.f(j x)) (λy.f y) == (λj.λx.f(j x)) f replace (λy.f y) with f
== (λx.f(f x)) apply (λj.λx.f(j x)) to f

Related

How to use quote and unquote to more faithfully translate The Reasoned Schemer into Racket?

(Details of my miniKanren in Racket setup appear at the bottom[1].)
The way quotes and unquotes work in The Reasoned Schemer appears not to match the way they work in Racket. For instance, verse 2 of chapter 2 suggests[2] the following function definition:
(run #f
(r )
(fresh (y x )
(== '(,x ,y) r )))
If I evaluate that, I get '((,x ,y)). If instead I rewrite it as this:
(run #f
(r )
(fresh (y x )
(== (list x y) r)))
I get the expected result, '((_.0 _.1)).
This might seem like a minor problem, but in many cases the required translation is extremely verbose. For instance, in exercise 45 of chapter 3 (page 34), the book provides, roughly[3] the following definition:
(run 5 (r)
(fresh (w x y z)
(loto (('g 'g) ('e w) (x y) . z))
(== (w (x y) z) r)))
In order to get the results they get, I had to rewrite it like this:
(run 5 (r)
(fresh (w x y z)
(loto (cons '(g g)
(cons (list 'e w)
(cons (list x y)
z))))
(== (list w (list x y) z)
r)))
[1] As described here, I ran raco pkg install minikanren and then defined a few missing pieces.
[2] Actually, they don't write precisely that, but if you heed the advice in the footnotes to that verse and an earlier verse, it's what you get.
[3] Modulo some implicit quoting and unquoting that I cannot deduce.
Use the backquote ` instead of the simple quote ' you have been using.

What causes an unbound variable error in Scheme?

I've started out with SICP and I'm new to Scheme. I've tried debugging this piece of code and even compared it to similar solutions.
(def (myFunc x y z)
(cond ((and (<= x y) (<= x z)) (+ (* y y) (* z z)))
((and (<= y x) (<= y z)) (+ (* x x) (* z z)))
(else (+ (* x x) (* y y)))))
This function returns the sum of the squares of two largest numbers.
When I run this, the interpreter gives out ";Unbound variable: y". Could you please explain the cause behind this error?
Help is greatly appreciated :)
The function-defining primitive in Scheme is called define, not def.
As it is, the whole (def ...) expression was treated as a function call to def. So its arguments' values needed to be found. The first argument (myFunc x y z) is a function call so its argument values needed to be found. Apparently your implementation wanted to find out the value of y first.
The R5RS standard says "The operator and operand expressions are evaluated (in an unspecified order) and the resulting procedure is passed the resulting arguments."
It is likely your implementation chooses the rightmost argument first, which leads to (<= x y) being evaluated first (because of special rules of evaluating the cond and and special forms), with y in its rightmost position.

SICP 2.16 interval-arithmetic (scheme)

This isn't a homework question, I'm just left unsatisfied with my understanding of interval arithmetic and the implications of exercise 2.16.
The interval arithmetic defined by section 2.14 does not exhibit the properties of normal arithmetic. Two should be equivalent operations, (r1*r2)/(r1 + r2) and 1/(1/r1 + 1/r2),
give different results. The exercise asks why this is the case, and if it is possible to construct an interval-arithmetic system in which this is not the case.
The section is addressing the calculation of error margins of resistance of electrical components. I'm not sure I understand what it would mean, in these terms, to multiply and divide intervals. What is the application to multiplying two intervals together?
Is it possible to construct an interval-arithmetic system without the problem in this example?
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#%_sec_2.1.4
(define (make-interval a b)
(cons a b))
(define (make-center-width c w)
(make-interval (- c w) (+ c w)))
(define (make-center-percent c p)
(make-center-width c (* c (/ p 100.0))))
(define (lower-bound i)
(car i))
(define (upper-bound i)
(cdr i))
(define (center i)
(/ (+ (upper-bound i) (lower-bound i)) 2))
(define (width i)
(/ (- (upper-bound i) (lower-bound i)) 2))
(define (percent i)
(* 100.0 (/ (width i) (center i))))
(define (add-interval x y)
(make-interval (+ (lower-bound x) (lower-bound y))
(+ (upper-bound x) (upper-bound y))))
(define (sub-interval x y)
(make-interval (- (lower-bound x) (lower-bound y))
(- (upper-bound x) (upper-bound y))))
(define (mul-interval x y)
(let ((p1 (* (lower-bound x) (lower-bound y)))
(p2 (* (lower-bound x) (lower-bound y)))
(p3 (* (lower-bound x) (lower-bound y)))
(p4 (* (lower-bound x) (lower-bound y))))
(make-interval (min p1 p2 p3 p4)
(max p1 p2 p3 p4))))
(define (div-interval x y)
(if (= (width y ) 0)
(error "division by interval with width 0")
(mul-interval x
(make-interval (/ 1.0 (upper-bound y))
(/ 1.0 (lower-bound y))))))
(define (parl1 r1 r2)
(div-interval (mul-interval r1 r2)
(add-interval r1 r2)))
(define (parl2 r1 r2)
(let ((one (make-interval 1 1)))
(div-interval one
(add-interval (div-interval one r1)
(div-interval one r2))))
(define (r1 (make-interval 4.0 3.2)))
(define (r2 (make-interval 3.0 7.2)))
(center (parl1 r1 r2))
(width (parl1 r1 r2))
(newline)
(center (parl2 r1 r2))
(width (parl2 r1 r2))
This happens because the operations in the interval arithmetic do not have the arithmetic structure of a field.
As Sussman says, the exercise is difficult -- you need to check each of the operations of the field structure, and see which one is not satisfied.
The exercise asks us to show that the interval arithmetic is not the arithmetic of the ranges of functions.
A function like f (x) = x^2 defined on a domain [-1, 1] has the
range [0,1], which is included in [-1,1] * [-1,1] = [-1,1], obtained by replacing the symbol x by the domain of the symbol x.
If we define a similar function that uses a different variable for each dimension, like in f(x,y) = x * y, then the range of this function, when defined on the domain [-1,1] * [-1,1], is the same as the interval [-1,1] * [-1,1] = [-1, 1], because x is used once, and so with y.
It happens that all the time when the function f(.., x, ..) is continous in each variable x we have the range arithmetics to be identical with interval arithmetics if each symbol is used only once in definition of f.
In the first formula of Alice, parallel resistor is computed
repeating 2 times the variable R1, and 2 times the variable R2,
and using the same argument the range of this function is included
in the product of the corresponding intervals obtained from the
formula of the function, by replacing each name by corresponding
domain interval, but it is not strictly the same.
We are asked either to rewrite any function such that the range of the rewritten function be the same as the interval obtained by applying the rewritten function's formula, wih names replaced by intervals equal to the domain of the corresponding name from the rewritten function, or to show that this is not possible for each possible function.
This problem is called dependency problem, and it is a large
problem, whose understanding is out of the purpose of SICP, and requires differential equations in multiple variables to solve it.
The purpose of this exercise is , as Sussman himself said, just to show that data can be encoded in multiple ways. The focus is not on mathematics , but on data abstraction.
The easiest way to understand the problem is looking at the very simple expression e = x/x where x is in [2,3]. If we use interval arithmetic, we get that e is in [2/3, 3/2], however second grade arithmetic shows that e=x/x=1. So what gives?
Well it is actually very simple: when using interval arithmetic I made the mistake of assuming x can have two different values at the same time.
the maximum value of e is given when the numerator is 3 and the denominator is 2, however since both should always be the same this is not possible.
So, is it ever possible to use interval arithmetic? Yes, when all intervals appear only once, since then you would not have the problem of different values for the same variable in different interval calculations.
Is it possible to create an arithmetic package which does not have this problem? No, since not every function can be written where every variable appears only once. This problem is known as the dependency problem.

Scheme-- how do procedures take other procedures as arguments?

Write a Scheme procedure named 'proc4' which takes 2 procedures as arguments (w,x) [note that w and x can be expected to work correctly when given two numbers as arguments]
and returns a procedure which takes 2 numbers (y,z) as arguments and returns the
procedure (w or x) which results in the greatest number when applied to y and z
(i.e. in C++ pseudocode if ((y w z) > (y x z)) {return w; } else {return x;} )
So I started
(define proc4(lamdda ( w x) (lambda y z)...
Then I wanted to do the if part. Something like
(if (> (apply w ( y z)) (apply x( w z))) but I keep getting errors.
I've been trying to find help on internet but everything I've seen so far does not make sense to me.
You can invoke function objects directly, without using apply:
(define (proc4 f g)
(lambda (x y)
(if (> (f x y) (g x y))
f
g)))
A bit of syntactic sugar for #ChrisJester-Young's answer - you can declare a procedure that returns another procedure like this:
(define ((proc4 f g) x y)
(if (> (f x y) (g x y))
f
g))
In the above code, the first procedure receives as parameters the procedures f and g, and in turn returns a procedure that receives as parameters x and y. We know that f and g are procedures because the way they're used inside the body of the definition, but they can have any name you want. Of course you can call the procedure in the usual way:
((proc4 + *) 10 20)
=> #<procedure:*>
The point of interest in this example is that procedures can also be passed as parameters (and returned as values), you don't need to apply them, just invoke the procedures received as parameters as you would with any other procedure. Also notice that all the answers to this question are equivalent, but the short-hand syntax that I'm using might not be available in all interpreters.
I cannot make much sense of this (obviously homework) question but I'd go for this:
(define proc4
(lambda (w x)
(lambda (y z)
(if (> (w y z) (x y z))
w
x))))

Getting the median of 3 values using scheme's

The problem this time is to get the median of three values (easy)
I did this:
(define (med x y z) (car(cdr(x y z)))
and it was accepted but when testing it:
(med 3 4 5)
I get this error:
Error: attempt to call a non-procedure
(2 3 4)
And when entering letters instead of number i get:
(md x y z)
Error: undefined varia
y
(package user)
Using something besides x y z I get:
(md d l m)
Error: undefined variable
d
(package user)
the question was deleted dont know how anyway
write a function that return the median of 3 values
Sorry for editing the question I got that I should put the values in order first not just a sill car and cdr thing so I did so
33> (define (med x y z)
(if(and(
(<x y) (<y z) y
if(and(
(<y x) (<x z) x z)))))
Warning: invalid expression
(if (and< (<x y) (<y z) y if (and ((<y x) (<x z) x z))))
but as u see Im getting a warning so what is wronge ?
You probably want to create a list, like this:
(define (med x y z) (car(cdr(list x y z)))
However, it seems like a waste to bundle up the values into a list just to undo them again. This would have the same effect:
(define (med x y z) y)
Note that as defined, (med . rest) is equivalent to (cadr rest) (except that med only takes three values). Personally, I would expect a function that's supposed to return the median of values to return, well, the median, regardless of list order. For example, (med 4 2 5) would return 4 and (3 0 9 6 5) would return 5.
As for the syntax error (which doesn't matter so much for writing med, since there is a better way using sort, length and list-ref), you don't have your parentheses in the right spots. Here's another way of writing what you have now, lining up terms with their siblings and to the right of their ancestors:
(if (and (
(<x y)
(<y z)
y
if
(and (
(<y x)
(<x z)
x
z
) ) ) ) )
The format for if is:
(if test-expr true-expr false-expr)
All of your terms are sub-terms of the conditional, and there's no true-expr or false-expr. You'd want to write your code as:
(if (and ...)
y
(if (...) ; we know that (not (and (< x y) (< y z))
x
z))
Note that you might be ably to simplfy the later tests, since you know the earlier tests are false.
You could also use a cond, which is clearer than a nested sequence of ifs:
(cond (test result)
(test result)
(test result)
... )
For your code, it would be:
(cond ((and ...) y)
((...) x)
(else z))
There's nothing too special about else (it's a syntactical construct rather than an expression, not that it matters much). You can use any value that evaluates to true (e.g. #t) instead.
Remember, parentheses surround both the function and arguments in Lisp ((foo 1 2 3), not foo(1, 2 ,3)), unlike mathematical notation where parentheses surround just the arguments.
while outis did a pretty good job of explaining the issue, there's one other important bit you need to know
(<x y)
calls the function named <x with the parameter y. you need to make sure you add a space inbetween the < and the x, like so:
(< x y)

Resources