How can I express the following function by a lambda term?
f(n) = T if n != 0.
F if n = 0.
n stands for a Church numeral.
I know that 0 := λf.λx.x where λx.x is the identity function and all other natural numbers can be expressed by n := λf.λx.f (f ... (f x)) which contains f n times more than the 0-term. E.g. 3 := λf.λx.f (f (f x)).
But how can I derive a valid λ-term for the function above? I think I need a y too for getting the T/F. Therefore I can express the number n by λf.(λxy.fxy), right? But what about the F and T? Is the following a right λ-term for the function above? λf.(λxy.fxy(yFT)) where T=λxy.x and F=λxy.y?
No, you're given the term for n. It is a function that expects two arguments, an f and a z:
isZero n = n ( ;; f, a function, expecting x
;; or the result of (f (f ... (f x) ...))
λx.
;; but we know what we want it to return, always: it is:
F ;; false, for n is _not_ 0
)
( ;; the initial x, in case n is ......... 0!
;; so we know what we want it to be, in case n is 0:
T ;; true, for n _is_ 0
)
and thus
isZero = λn.n(λx.F)T
If n was 0, isZero n will return T; and otherwise, F:
{0}(λx.F)T = T
{1}(λx.F)T = (λx.F)T = F
{2}(λx.F)T = (λx.F)((λx.F)T) = F
{3}(λx.F)T = (λx.F)((λx.F)((λx.F)T)) = F
....
Related
I am trying to create a recursive function that divides two integers n and m and then displays the result and the remainder of the division.
Basicly I created two separate functions which do exactly what I want:
let rec div1 (n: int, m: int): int =
if n<m then n else div1(n-m, m)
printfn "Remainder: %i" (div1(5,5))
let rec div2 (n: int, m: int): int =
if n<m then 0 else 1+div2(n-m, m)
printfn "Result: %i" (div2(5,5))
The thing is, I want to do them both at once, I mean in one function like let rec div12 (n: int) (m : int): int * int = , not in two separate.
I am not sure how exactly this would work on F#.
A function may return more than just a number. For example, a function may return a tuple of two numbers:
let f x = (x, x+5)
f 5
> (5, 10)
Further, you can destructure return value of such a function in a similar way:
let (x, y) = f 5
x
> 5
y
> 10
Now we can use this to have our div+mod function return two results - remainder and quotient:
let rec divMod n m =
if n < m
then
(n, 0)
else
let (remainder, quotient) = divMod (n-m) m
(remainder, quotient + 1)
Note how this function simply combines results of your div1 and div2 in a tuple, then destructures them after the recursive call.
divMod 5 5
> (0, 1)
divMod 5 3
> (2, 1)
divMod 7 3
> (1, 2)
Also note that I'm using curried parameters divMod n m instead of tupled parameters as you do div1 (n, m). Ultimately this is a matter of taste, but as a pro tip, I'd like to point out that curried parameters turn out to be much more useful in practice.
I'm very new to Haskell and am trying to write a simple function that will take an array of integers as input, then return either the product of all the elements or the average, depending on whether the array is of odd or even length, respectively.
I understand how to set a base case for recursion, and how to set up boolean guards for different cases, but I don't understand how to do these in concert.
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = arrayFunc (x:xs) = x * arrayFunc xs
| (length array) % 2 == 0 = ((arrayFunc (x:xs) = x + arrayFunc xs) - 1) `div` length xs
Currently I'm getting an error
"parse error on input '='
Perhaps you need a 'let' in a 'do' block?"
But I don't understand how I would use a let here.
The reason you have guards is because you are trying to determine the length of the list before you actually look at the values in the list.
Rather than make multiple passes (one to compute the length, another to compute the sum or product), just compute all of the values you might need, as you walk the list, and then at the end make the decision and return the appropriate value:
arrayFunc = go (0, 1, 0, True)
where go (s, p, len, parity) [] =
if parity then (if len /= 0 then s `div` len else 0)
else p
go (s, p, len, parity) (x:xs) =
go (s + x, p * x, len + 1, not parity) xs
There are various things you can do to reduce memory usage, and the recursion is just reimplementing a fold, but this gives you an idea of how to compute the answer in one pass.
Define an auxiliary inner function like that:
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = go1 array
| (length array) % 2 == 0 = go2 array
where
go1 (x:xs) = x * go1 xs
go2 (x:xs) = ((x + go2 xs) - 1) `div` length xs
This deals only with the syntactical issues in your question. In particular, [Integer] is not an array -- it is a list of integers.
But of course the name of a variable doesn't influence a code's correctness.
Without focus on recursion this should be an acceptable solution:
arrayFunc :: (Integral a) => [a] -> a
arrayFunc ls
| n == 0 = 1
| even n = (sum ls) `div` (fromIntegral n)
| otherwise = product ls
where
n = length xs
I want to define a function f w/ 2 explicit arguments. The types of the arguments and value of f are applications of some g. Suppose the arguments' types are g x y and g z w. The tricky part is that f's value must depend on the unifiability of x and z. Below is a naive attempt at defining f that fails. How should I tackle this?
Inductive A := a | a0 | fa.
Inductive B := b | b0.
Parameter C: Type.
Parameter g: A -> B -> C.
Parameter CT:> C -> Type.
Parameter gab: g a b.
Parameter ga0b: g a0 b.
Definition f {x y z w}(n: g x y)(m: g z w) :=
ltac:(match x with z => exact (g z b) | _ => exact (g fa b) end).
Compute f gab ga0b. (*= g fa b: C*)
Compute f gab gab. (*! = g fa b: C !*)
f's value must depend on the unifiability of x and z
It is impossible to write such a definition. Suppose you could write a function that could tell whether or not two natural numbers unified, call it unify_nat : nat -> nat -> bool. Consider now the functions
F := fun x y : nat => if unify_nat (x + y) (y + x) then True else False
G := fun x y : nat => if unify_nat (x + y) (x + y) then True else False
We can prove, because addition is commutative, that forall x y, F x y = G x y. But then unify_nat (x + y) (y + x) must return true, even though x + y and y + x do not unify.
There are two things you can do: (1) you can ask not if the terms unify, but if they are propositionally equal; and (2) you can write a notation, or an alias, which is like syntactic sugar for a definition.
1.
The command Scheme Equality will generate an equality decision function for most inductive types:
Scheme Equality for A.
Definition f {x y z w}(n: g x y)(m: g z w) :=
if A_beq x z then g z b else g fa b.
Compute f gab ga0b. (*= g fa b: C*)
Compute f gab gab. (*= g a b: C*)
2.
We can create evars with open_constr:(_) and use unification to infer the types of n and m:
Ltac f_tac n m :=
let x := open_constr:(_) in
let y := open_constr:(_) in
let z := open_constr:(_) in
let w := open_constr:(_) in
let n := constr:(n : g x y) in
let m := constr:(m : g z w) in
match x with z => exact (g z b) | _ => exact (g fa b) end.
Notation f n m := (ltac:(f_tac n m)) (only parsing).
Compute f gab ga0b. (*= g fa b: C*)
Compute f gab gab. (*= g a b: C*)
I'm trying to put the last element of a list in the front of the list while keeping the rest of the elements in the same order N times. I can do it once with this function, but I want to add another parameter to the function so that the function in called N times.
Code:
fun multcshift(L, n) =
if null L then nil
else multcshift(hd(rev L)::(rev(tl(rev L))));
Thanks
To make the parameter n work, you need recursion. You need a base case at which point the function should no longer call itself, and a recursive case where it does. For this function, a good base case would be n = 0, meaning "shift the last letter in front 0 times", i.e., return L without modification.
fun multcshift(L, n) =
if n = 0
then L
else multcshift( hd(rev L)::rev(tl(rev L)) , n - 1 )
The running time of this function is terrible: For every n, reverse the list three times!
You could save at least one of those list reversals by not calling rev L twice. E.g.
fun multcshift (L, 0) = L
| multcshift (L, n) =
let val revL = rev L
in multcshift ( hd revL :: rev (tl revL) , n - 1 ) end
Those hd revL and rev (tl revL) seem like useful library functions. The process of applying a function to its own output n times seems like a good library function, too.
(* Return all the elements of a non-empty list except the last one. *)
fun init [] = raise Empty
| init ([_]) = []
| init (x::xs) = x::init xs
(* Return the last element of a non-empty list. *)
val last = List.last
(* Shift the last element of a non-empty list to the front of the list *)
fun cshift L = last L :: init L
(* Compose f with itself n times *)
fun iterate f 0 = (fn x => x)
| iterate f 1 = f
| iterate f n = f o iterate f (n-1)
fun multcshift (L, n) = iterate cshift n L
But the running time is just as terrible: For every n, call last and init once each. They're both O(|L|) just as rev.
You could overcome that complexity by carrying out multiple shifts at once. If you know you'll shift one element n times, you might as well shift n elements. Shifting n elements is equivalent to removing |L| - n elements from the front of the list and appending them at the back.
But what if you're asked to shift n elements where n > |L|? Then len - n is negative and both List.drop and List.take will fail. You could fix that by concluding that any full shift of |L| elements has no effect on the result and suffice with n (mod |L|). And what if n < 0?
fun multcshift ([], _) = raise Empty
| multcshift (L, 0) = L
| multcshift (L, n) =
let val len = List.length L
in List.drop (L, len - n mod len) #
List.take (L, len - n mod len) end
There are quite a few corner cases worth testing:
val test_zero = (multcshift ([1,2,3], 0) = [1,2,3])
val test_empty = (multcshift ([], 5); false) handle Empty => true | _ => false
val test_zero_empty = (multcshift ([], 0); false) handle Empty => true | _ => false
val test_negative = (multcshift ([1,2,3,4], ~1) = [2,3,4,1])
val test_nonempty = (multcshift ([1,2,3,4], 3) = [2,3,4,1])
val test_identity = (multcshift ([1,2,3,4], 4) = [1,2,3,4])
val test_large_n = (multcshift [1,2,3,4], 5) = [4,1,2,3])
val test_larger_n = (multcshift [1,2,3,4], 10) = [3,4,1,2])
Eventually what I want is what x represents:
let x = (something, (myfunc1 para1));;
so that when calling x, I get a tuple, but when calling (snd x) para, I will get a return value of myfunc1 para.
What I'm trying is like this:
let myfunc2 para1 para2 =
let myfunc1 para2 = ... in
( (fst para1), (myfunc1 para2) );;
And I want to call myfunc2 like this:
let x = myfunc2 para1 to get what I described above. However, what I get is just a function which when called with para1 will return a regular tuple, not a (something, function) tuple
You have a useless para2 parameter in your definition. The correct way is:
let myfunc2 para1 =
let x = ... in
let myfunc1 para2 = ... in
( x, myfunc1 );;
But it would help if we could speak about a concrete example. You are misunderstanding something obvious, but I do not know what.
Here is a concrete example. Suppose we want a function f which accepts a number n and returns a pair (m, g) where m is the square of n and g is a function which adds n to its argument:
let f n =
let m = n * n in
let g k = n + k in
(m, g)
Or shorter:
let f n = (n * n, fun k => n + k)
Now to use this, we can do:
let x = f 10 ;;
fst x ;; (* gives 100 *)
snd x ;; (* gives <fun> *)
snd x 5 ;; (* gives 15, and is the same thing as (snd x) 5 *)
Now let us consider the following bad solution in which we make the kind of mistake you have made:
let f_bad n k =
let m = n * n in
let g k = n + k in
(m, g k)
Now f_bad wants two arguments. If we give it just one, we will not get a pair but a function expecting the other argument. And when we give it that argument, it will return a pair of two integers because (m, g k) means "make a pair whose first component is the integer m and the second component is g applied to k, so that is an integer, too."
Another point worth making is that you are confusing yourself by calling two different things para2. In our definition of f_bad we also confuse ourselves by calling two different things k. The k appearing in the definition of g is not the same as the other k. It is better to call the two k's different things:
let f_bad n k1 =
let m = n * n in
let g k2 = n + k2 in
(m, g k1)
Now, does that help clear up the confusion?