I am trying to understand xor in context on lambda calculus. I understand xor (Exclusive or) as boolean logic operation in https://en.wikipedia.org/wiki/Exclusive_or
and the truth table of xor.
But how why is it true as a xor b=(a)((b)(false)(true))(b)
from http://safalra.com/lambda-calculus/boolean-logic/
it is indeed what what expect in lambda calculus. When I saw
true=λab.a
false=λab.b
I kinda have to see the true and false as a lambda calc true and false since it returns the first element in case of true. But is it correct to understand that the xor here is also a name but not the same as xor in boolean logic?
Intuitively, we can think of A XOR B as
if A, then not B
otherwise, B
.... or in some pseudocode:
func xor (a,b)
if a then
return not b
else
return b
Let's get lambda calculusing
true := λa.λb.a
false := λa.λb.b
true a b
// a
false a b
// b
next we'll do not
not := λp.p false true
not true a b
// b
not false a b
// a
we can do if next (note, that this is sort of silly since true and false already behave like if)
if := λp.λa.λb.p a b
if true a b
// a
if false a b
// b
Ok, lastly write xor
xor := λa.λb.if a (not b) b
(xor true true) a b
// b
(xor true false) a b
// a
(xor false true) a b
// a
(xor false false) a b
// b
Remember if is kind of dumb here, we can just remove it
xor := λa.λb.a (not b) b
Now if we want to write it all with pure lambda, just replace the not with its definition
xor := λa.λb.a (not b) b
->β [ not := λp.p false true ]
xor := λa.λb.a ((λp.p false true) b) b
->β [ p := b ]
xor := λa.λb.a (b false true) b
At this point, you can see we have the definition from your question
a xor b = (a)((b)(false)(true))(b)
But of course that introduced additional free variables false and true – you can replace those with a couple additional beta reductions
xor := λa.λb.a (b false true) b
->β [ false := (λa.λb.b) ]
xor := λa.λb.a (b (λa.λb.b) true) b
->β [ true := (λa.λb.a) ]
// pure lambda definition
xor := λa.λb.a (b (λa.λb.b) (λa.λb.a)) b
Consider a(b F T)b,the middle expression is essentially (not b),so a(not b)b gives true only when a and b are different.
Related
Is there a way to simplify AND/OR logical operators?
Let's say I have the following rule:
a AND (b AND/OR c)
Using the logical operators I will do as follow:
a & b & c | a & (b|c)
Can I do it so that I have something like a & (b &| c)?
Let's break it down into two parts.
a & b & c | a & (b|c) can be TRUE if either a & b & c (Part 1) is TRUE OR a & (b|c) (Part2) is TRUE.
which means if all of a, b and c are TRUE (Part 1) OR
a is TRUE and either of b or c is TRUE. (Part 2)
but if a and b is TRUE Part 2 is already TRUE so we don't really need c and part 1 then.
Hence, this ends up only with part 2 which is :
a & (b|c)
I'm trying to prove the following Lemma in coq --
Lemma less_than_two_equivalent: forall x, less_than_two x = true -> x < 2.
based on the definition below.
Fixpoint less_than (a b:nat): bool:=
match a, b with
|0, 0 => false
|0, _ => true
|S a', 0 => false
|S a', S b' => less_than a' b'
end.
Fixpoint less_than_two (x:nat) : bool := if less_than x 2 then true else false.
Mathematically, there are only 2 cases, 0 or 1. And destructionshould be the hammer, but there won't be enough information about the S x for further reasoning.
Should I modify the less_than into inductive datatypes? If not, how to resolve it?
Let me begin by redefining less_than_two. First, it's not recursive, so there is no point in defining it as a Fixpoint. Next, if less_than x 2 then true else false is essentially the same thing as less_than x 2. And at this point I wouldn't bother with introducing a new definition, so your lemma becomes
Lemma less_than_two_equivalent x: less_than x 2 = true -> x < 2.
Proof.
do 2 (destruct x; auto); simpl.
destruct x; discriminate.
Qed.
I don't know what went wrong with your proof exactly, but you might have forgotten to destruct x one more time. When you see less_than x 0 = true -> S (S x) < 2 you can't still use discriminate to finish your goal, because evaluation is blocked on the variable -- less_than first pattern-matches on the a parameter and only then checks b. Destruction of x unblocks computation and lets Coq see that you have false = true as your premise, hence the goal becomes provable.
Note that this depends on the particular implementation of the comparison function. Had you chose this one
(* (!) the [struct] annotation is important here, as well as as
the order of the parameters [b, a] in the match expression *)
Fixpoint less_than' (a b : nat) {struct b} : bool :=
match b, a with
| 0, _ => false
| _, 0 => true
| S b', S a' => less_than' a' b'
end.
you would have a bit simpler proof (one less destruct):
Lemma less_than_two_equivalent x: less_than' x 2 = true -> x < 2.
Proof.
do 2 (destruct x; auto).
discriminate.
Qed.
In functional programming, what is the name (or name of the concept) of the following functional operator P?:
Given two functions f and g, and predicate function p, P(p, f, g) is the function
x → if (p(x)) f(x) else g(x)
I am wondering whether this operator has an established name, so that I can use that name in my code. (That is, I want to give P a conventional name.)
I would say it's the if operator lifted into the function monad.
For example in Haskell, you can literally do
import Control.Monad
let if' c t f = if c then t else f -- another common name is `ite`
let ifM = liftM3 if' -- admittedly the type of this is too generic
-- ^^^^^^^^^^
let example = ifM even (\x -> "t "++show x) (\x -> "f "++show x)
example 1 -- "f 1"
example 2 -- "t 2"
Another haskell example Point-wise conditional in Boolean library
cond :: (Applicative f, IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a -> f a
it takes Applicative that holds bool, two another Applicatives with values for True and False cases and produces Applicative result.
There are different types that are Applicative and function is just one of them.
> f = cond (\x -> x > 1) (\x -> x / 10) (\x -> x * 10)
> f 2.0
# 0.2
> f 0.13
#1.3
Optional value Maybe is another useful example
> cond (Just True) (Just 10) (Just 20)
# Just 10
> cond (Just True) (Just 10) Nothing
# Nothing
List is also Applicative
> cond [True, False, True] [10] [1, 2]
# [10,10,1,2,10,10]
> cond [True, False, True] [10] [1]
# [10, 1, 10]
> cond [True, False, True] [10] []
# []
Is it possible to have nested if without else statements. I wrote the following useless program to demonstrate nested ifs. How do I fix this so it's correct in terms of syntax. lines 5 and 6 gives errors.
let rec move_helper b sz r = match b with
[] -> r
|(h :: t) ->
if h = 0 then
if h - 1 = sz then h - 1 ::r
if h + 1 = sz then h + 1 ::r
else move_helper t sz r
;;
let move_pos b =
move_helper b 3 r
;;
let g = move_pos [0;8;7;6;5;4;3;2;1]
You can't have if without else unless the result of the expression is of type unit. This isn't the case for your code, so it's not possible.
Here's an example where the result is unit:
let f x =
if x land 1 <> 0 then print_string "1";
if x land 2 <> 0 then print_string "2";
if x land 4 <> 0 then print_string "4"
You must understand that if ... then is an expression like any other. If no else is present, it must be understood as if ... then ... else () and thus has type unit. To emphasize the fact that it is an expression, suppose you have two functions f and g of type, say, int → int. You can write
(if test then f else g) 1
You must also understand that x :: r does not change r at all, it constructs a new list putting x in front of r (the tail of this list is shared with the list r). In your case, the logic is not clear: what is the result when h=0 but the two if fail?
let rec move_helper b sz r = match b with
| [] -> r
| h :: t ->
if h = 0 then
if h - 1 = sz then (h - 1) :: r
else if h + 1 = sz then (h + 1) :: r
else (* What do you want to return here? *)
else move_helper t sz r
When you have a if, always put an else. Because when you don't put an else, Java will not know if the case is true or false.
I have the following code for Trial Divison Algorithm in Maple:
TrialDivision := proc( n :: integer )
if n <= 1 then
false
elif n = 2 then
true
elif type( n, 'even' ) then
false
else
for local i from 3 by 2 while i * i <= n do
if irem( n,i) = 0 then
return false
end if
end do;
true
end if
end proc:
which I got from http://rosettacode.org/wiki/Primality_by_trial_division#MATLAB. But when I try to run it, it is giving me the following error: Error, unexpected local declaration in procedure body.
Does anyone know what I am doing wrong?
Allowing local declarations throughout the procedure body is a somewhat recent addition to the Maple language.
You could change it to this, say.
TrialDivision := proc( n :: integer )
local i;
if n <= 1 then
false
elif n = 2 then
true
elif type( n, 'even' ) then
false
else
for i from 3 by 2 while i * i <= n do
if irem( n,i) = 0 then
return false
end if
end do;
true
end if
end proc: