Issue with Demorgan Definition of AND #125
Copy link
Copy link
Closed
Description
Thank you for the project! Was super fun!
I tried defining AND in terms of NOT and OR and my definition does not seem to work. I believe this to be a bug? https://en.wikipedia.org/wiki/De_Morgan's_laws
AND:=λab.NOT(OR(NOTa)(NOTb))
AND: λa.λb.(λa.λb.λc.acb)((λa.λb.a(λa.λb.a)b)((λa.λb.λc.acb)a)((λa.λb.λc.acb)b))
<assignment>
> AND FALSE FALSE
λb.λc.c
<function, church numeral 0, church boolean false>
> AND FALSE TRUE
λb.λc.c
<function, church numeral 0, church boolean false>
// This case here doesn't seem to evaluate properly?
> AND TRUE FALSE
λb.λc.b
<function, church boolean true>
> AND TRUE TRUE
λb.λc.b
<function, church boolean true>(+)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
evinism commentedon Jan 19, 2024
Tried doing this myself, defining
NOTandOR, withThis one copied from your issue above,
Seems to give me a proper
AND:Trying this out with
NOT:=λa.λb.λc.acb, I can recreate the issue you've found. Something's very fishy indeed.stevenhuyn commentedon Jan 19, 2024
Ah my bad on not giving the other defs
evinism commentedon Jan 20, 2024
Reproducing fails with
NOT:=λm.λn.λo.mon, which should be equivalent. Some naming issue pops upevinism commentedon Jan 20, 2024
These should be equivalent, but they execute differently:
evinism commentedon Jan 20, 2024
Yikes, dependent on both a name collision in the automated alpha conversion and the target variable. (Middle is incorrect)
evinism commentedon Jan 20, 2024
Reproducing in the spec: #127
anderium commentedon Jul 12, 2024
Let's analyse it, under the preface that I didn't actually run any of this and it's purely manual code analysis.
To be on the same page, the issue is that spec occurs with this piece of AST:
This function does not contain$\epsilon_1$ , so this will not lead to any collisions, but the $\alpha$ -reduction cannot know this ahead of time. (Or at least, shouldn't have to.) (The case where it does contain $\epsilon_1$ is actually already handled correctly.)
In the capture avoidance step it then has to generate a new name. As far as the system is concerned, the free variables are:
Using these variables, it thinks the first safe free name is$\epsilon_1$ , so changes the
alphaSafeExpressiontoHowever, the resursive application of the reduction on the body of the$\epsilon_1$ value.
alphaSafeExpressionthen updates thelambda-explorer/src/lib/lambda/operations.ts
Line 138 in 0fd8e7c
So in addition to the three cases already mentioned, there is a fourth requirement that arguments should not change to the name you are trying to replace. As mentioned, if that name does occur in the body of the function it already works; it will appear in the
freeInExpressionBodyarray.lambda-explorer/src/lib/lambda/operations.ts
Lines 112 to 115 in 0fd8e7c
// 4: isn't the argument name that is being replaced.I.e. solved by adding
nameToReplaceinto the array created here:lambda-explorer/src/lib/lambda/operations.ts
Lines 120 to 122 in 0fd8e7c
It may also be solved by not doing any replacement at all if
nameToReplacedoes not occur in thefreeInExpressionBodyarray.So why did I say that
freeInExpressionBodyis wrong?The variable
bis obviously bound in the function. This line should probably useexpressioninstead ofexpression.body.lambda-explorer/src/lib/lambda/operations.ts
Line 116 in 0fd8e7c
Although in that case, the variable should be part of
argNames, so that line should also useexpressioninstead ofexpression.body. And unsurprisingly that should lead to the same result, only shifting the array in which the function argument itself occurs.lambda-explorer/src/lib/lambda/operations.ts
Line 119 in 0fd8e7c
Exclude the nameToReplace from valid capture avoidance
Exclude the nameToReplace from valid capture avoidance
evinism commentedon Mar 19, 2026
Fixed in #136! Thanks for your patience!