4

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?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
echo
  • 767
  • 2
  • 9
  • 24
  • by the way, I assume true=λab.a false=λab.b is the same thing as true=(λa.b.)a false=(λa.b.) b the latter is more text book style – echo Oct 17 '17 at 07:41
  • 1
    lambda calculus logic is the same as in boolean logic. in lamba calculus there are no values, only symbols (names). TRUE is not only function, but also a name that describes it. and when the result of evaluation is λab.a, it's not important it's a function, more important is it's a function described by symbol TRUE. – rsm Oct 17 '17 at 09:26
  • 1
    also see: [*Church Encoding*](https://en.wikipedia.org/wiki/Church_encoding) – all values are functions, even numbers `zero := λf.λx.x`, `one := λf.λx.f x`, `two := λf.λx.f (f x)`, etc – Mulan Oct 17 '17 at 17:27

2 Answers2

16

Intuitively, we can think of A XOR B as

  1. if A, then not B
  2. 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
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • related: https://stackoverflow.com/questions/37119381/can-xor-be-expressed-using-ski-combinators – cool answer showing XOR derived from [SKI combinators](https://en.wikipedia.org/wiki/SKI_combinator_calculus) – Mulan Oct 17 '17 at 18:29
0

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.