public class lcei
{
static expr I, K, S, nil;
public static expr ap (expr f, expr a)
{
return new expr ("ap", 2, f, a, nil);
}
public static expr transym (expr d1, expr d2)
{
return new expr ("transym", 2, d1, d2, nil);
}
public static expr defI (expr a)
{
return new expr ("defI", 1, a, nil, nil);
}
public static expr defK (expr a, expr b)
{
return new expr ("defK", 2, a, b, nil);
}
public static expr defS (expr a, expr b, expr c)
{
return new expr ("defS", 3, a, b, c);
}
public static expr axm (expr a, expr b)
{
return new expr ("axm", 2, a, b, nil);
}
public static expr DBVar (int l)
{
return new expr ("DBVar", l, 0, nil, nil, nil);
}
public static expr DBLambda (expr x)
{
return new expr ("DBLambda", 1, x, nil, nil);
}
public static expr DB_Subst (expr x, expr a)
{
return new expr ("DB_Subst", 2, x, a, nil);
}
public static boolean equal (expr x, expr y)
{
if (x == nil)
{
if (y == nil)
return true;
return false;
}
if (y == nil)
return false;
if (!(x.node.equals(y.node)))
return false;
if (x.nprem != y.nprem)
return false;
for (int i=0; i= m)
return DBVar (x.level + n);
else
return x;
}
if (x.node.equals ("DBLambda"))
return DBLambda (dbshift (m+1, n, x.prem[0]));
return new expr (x.node, x.level, x.nprem,
dbshift (m, n, x.prem[0]),
dbshift (m, n, x.prem[1]),
dbshift (m, n, x.prem[2]));
}
public static expr DBsubst (int n, expr y, expr z)
{
if (y == nil)
return nil;
if (y.node.equals ("DBVar"))
{
if (y.level == n)
return z;
if (y.level > n)
return DBVar (y.level - 1);
}
if (y.node.equals ("ap"))
return ap (DBsubst (n, y.prem[0], z),
DBsubst (n, y.prem[1], z));
if (y.node.equals ("DBLambda"))
return DBLambda (DBsubst (n+1, y.prem[0], dbshift (0, 1, z)));
return new expr (y.node, y.level, y.nprem,
DBsubst (n, y.prem[0], z),
DBsubst (n, y.prem[1], z),
DBsubst (n, y.prem[2], z));
}
public static expr left (expr x)
{
if (x.node.equals ("ap"))
return ap (left(x.prem[0]), left(x.prem[1]));
if (x.node.equals ("transym"))
{
if (equal (left(x.prem[0]), left(x.prem[1])))
return right(x.prem[0]);
return I;
}
if (x.node.equals ("defI"))
return ap (I, left(x.prem[0]));
if (x.node.equals ("defK"))
return ap (ap (K, left(x.prem[0])), left(x.prem[1]));
if (x.node.equals ("defS"))
return ap (ap (ap (S, left(x.prem[0])), left(x.prem[1])), left(x.prem[2]));
if (x.node.equals ("axm"))
return x.prem[0];
if (x.node.equals ("DB_Subst"))
return ap (DBLambda (x.prem[0]), x.prem[1]);
return x;
}
public static expr right (expr x)
{
if (x.node.equals ("ap"))
return ap (right(x.prem[0]), right(x.prem[1]));
if (x.node.equals ("transym"))
{
if (equal (left(x.prem[0]), left(x.prem[1])))
return right(x.prem[1]);
return I;
}
if (x.node.equals ("defI"))
return right(x.prem[0]);
if (x.node.equals ("defK"))
return right(x.prem[0]);
if (x.node.equals ("defS"))
return ap (ap (right(x.prem[0]), right(x.prem[2])), ap (right(x.prem[1]), right(x.prem[2])));
if (x.node.equals ("axm"))
return x.prem[1];
if (x.node.equals ("DB_Subst"))
return DBsubst (0, x.prem[0], x.prem[1]);
return x;
}
public boolean atom (expr x)
{
if (x.node.equals ("ap"))
return false;
return true;
}
expr transym1 (expr ab, expr cd)
{
if (equal (ab, cd))
return right (ab);
if (equal (left(ab), right(ab)))
return cd;
return transym (ab, cd);
}
expr sym (expr ab)
{
return transym1 (ab, left(ab));
}
expr trans (expr ab, expr bc)
{
return transym1 (sym(ab), bc);
}
public static void main (String args[])
{
nil = (expr) null;
I = new expr ("I", 0, nil, nil, nil);
K = new expr ("K", 0, nil, nil, nil);
S = new expr ("S", 0, nil, nil, nil);
expr x;
x = ap (K, ap (S, I));
x.print (System.out);
System.out.println ("---");
x = defI (K);
left(x).print (System.out);
System.out.println ("");
x = transym (ap(S,K), ap(S,K));
left(x).print (System.out);
System.out.println ("");
x = DB_Subst (DBVar(0), K);
left(x).print (System.out);
System.out.print (" = ");
right(x).print (System.out);
}
}