Would like to do the follow reverse conversion from SKI expressions to lambda expressions:
L[I] = λx.x
L[K] = λx.λy.x
L[S] = λx.λy.λz.(x z (y z))
L[(E₁ E₂)] = (L[E₁] L[E₂])
The conversion need not involve any beta-reduction. But I would nevertheless like to do a special beta-reduction. Whenever there is a linear redex or a unit redex:
(λx.E₁)E₂ x occurs at most once in E₁
I want to reduce it to:
E₁[x/E₂]
This seems to be a safe reduction in the sense, that it doesn't make the redex any larger, it only moves the position of E₂ or even eliminates E₂ if x doesn't occur. Respectively does a rename. Example:
L[S(S(K(S(KS)K))S)(KK)] = λx.λy.λz.xzy
Any Prolog implementation around?
Here is an implementation based on deBruijn indexes, and based on the Prolog answers here . The first part, translating L[_] from wikipedia into deBruijn indexes gives:
The new predicates in the linear simplification are simplify/2, subst2/4, notin/2 and oncein/2. shift/4 is exactly as in the Prolog answers here. The predicate subst2/4 in contrast to subst/4 calls simplify/2 to build application terms:
The predicates notin/2 and oncein/2 split the "at most once" into "not" and "exactly once":
This is the question problem solved:
The example doesn't completely converse with this bracket abstraction here: