typedef int Tree;
typedef int INT;
typedef int TREE;
typedef int BitStream;
#define DESCEND xx
Tree lastRight, accumulate;
// A bijective pairing.
TREE Pair (TREE yy, TREE xx)
{
// x - ~x = x - (-1 - x) = 2 * x + 1
return yy - ~yy << xx;
}
// The second component of a pair.
TREE Right (TREE xx)
{
return lastRight = xx % 2 ? 0 : 1 + Right (xx / 2);
}
// The first component. Note that we leave the other component in lastRight.
TREE Left (TREE xx)
{
return xx / 2 >> Right (xx);
}
// Encoding
// PI(A,B) = Pair(0,Pair(A,B))
// LAMBDA(A,B) = Pair(1,Pair(A,B))
// APPLY(A,B) = Pair(2,Pair(A,B))
// STAR = Pair(3,0) = 7
// BOX = Pair(3,1) = 14
// VAR(n) = Pair(4+2n,0) = 9 + 4n [n >= 0]
// The empty context is 0, and the context Gamma,A is Pair (A,Gamma).
// STAR and BOX are the only terms x with (x&2)!=0
// Increment the index of each variable in xx. Uses Subst.
// Making this a macro means that we can absorb an "=" and a "(" into the macro.
#define Lift(xx) Subst (4, 13, -4, xx)
// Substitute yy for vv in term, and normalise. Variables > yy get adjusted by
// -context. [The precise normalisation is: if yy and term are normal, and the
// substitution has a normal form, then the normal form is returned.]
TREE Subst (INT vv, TREE yy, INT context, TREE term)
{
Tree
aux = Left (term), // The operation of term.
xx = lastRight; // The body of term.
{
return
aux - 2 ?
aux > 2 ?
// Variable or Star or Box.
aux - vv ? term - (aux > vv) * context : yy :
// aux = 0 or aux = 1: lambda or pi. The stray 'term =' below is
// harmless, but allows us to push the '=' into the Lift macro.
Pair (aux, Pair (Subst (vv, yy, context, Left (xx)),
Subst (vv+2, term = Lift (yy), context, Right (xx))))
:
// Application. Use Apply.
Apply (Subst (vv, yy, context, Left (xx)),
Subst (vv, yy, context, Right (xx)));
}
}
// Apply yy to xx and normalise. [Precisely, if yy and xx are normal, and
// yy(xx) is normalisable, Apply(yy,xx) returns the normal form of yy(xx).
TREE Apply (TREE yy, TREE xx)
{
return Left (yy) - 1
// 5 << x == Pair(2,x)
? 5 << Pair (yy, xx)
: Subst (4, xx, 4, Right (lastRight));
}
// We use xx as a bit stream. The MAYBE macro tests the next bit for us.
#define MAYBE (xx /= 2) % 2 &&
// Derive parses a bit stream into terms of CoC and normalises everything. The
// outputs are accumulated into the variable yy. We also recurse, so as to
// cover all the BitStreams which are < xx.
TREE Derive (BitStream xx)
{
Tree
aux,
auxTerm,
// The axiom.
context = 0,
term = 7,
type = 14;
// Inside the while condition is the main recursion that makes us monotone.
// It doesn't need to be inside the while, but that allows us to compress the
// "),". It also means we get called more often, which makes "accumulate"
// bigger...
while (DESCEND && Derive (xx - 1), MAYBE (1))
// Get another term.
auxTerm = Left (Left (Derive (xx))),
// And get its type.
aux = Left (lastRight),
// And get the left-over bit-stream. This leaves the context from
// the sub-derivation in lastRight.
xx = Left (lastRight),
// Rules that depend on two antecedents... The two contexts (one is in
// lastRight) must be the same.
context - lastRight || (
// APPLY. type must be PI(aux,-).
Left (type) || Left (lastRight) - aux ||
MAYBE (type = Subst (4, auxTerm, 4, lastRight),
term = Apply (term, auxTerm)),
// Weakening. auxType must be STAR or BOX. The / 2 & MAYBE
// combines MAYBE with testing the correct bit of auxType. It is
// safe to do this immediately after an APPLY above, because APPLY
// does not change contexts.
aux / 2 & MAYBE ( context = Pair (auxTerm, context),
term = Lift (term),
type = Lift (type) )
),
context && MAYBE (
// If we get here, we are either going to do PI formation or LAMBDA
// introduction. PI formation requires type to be STAR or BOX. We
// allow LAMBDA introduction whenever the context is non-empty.
// This extension is a conservative extension of CoC.
term = Pair (
// Because of the && in MAYBE, this subexpression returns a
// boolean 1 if we're doing LAMBDA introduction, 0 if we're
// doing PI formation. The ~type&2| ensures that we do LAMBDA
// introduction if type is not the Star or Box needed to do PI
// formation.
~type & 2 | MAYBE (
// If we're doing lambda introduction on term, then we also
// need to do a PI formation on type. This is always
// non-zero. 1 << x = Pair(0,x).
type = 1 << Pair (Left (context), type)),
Pair (Left (context), term)),
// Remove the context item we just used.
context = lastRight ),
// If type is STAR or BOX then we allow variable introduction.
type / 2 & MAYBE (
context = Pair (term, context),
type = Lift (term),
term = 9 ); // Pair (4, 0)
{
// Pair term, type, context, and xx together, and chuck it all onto
// accumulate.
return accumulate = Pair (Pair (term, Pair (type, Pair (xx, context))),
accumulate);
}
}
TREE main ()
{
return Derive (2);
}
dHlwZWRlZiBpbnQgVHJlZTsKdHlwZWRlZiBpbnQgSU5UOwp0eXBlZGVmIGludCBUUkVFOwp0eXBlZGVmIGludCBCaXRTdHJlYW07CiNkZWZpbmUgREVTQ0VORCB4eAoKVHJlZSBsYXN0UmlnaHQsIGFjY3VtdWxhdGU7CgovLyBBIGJpamVjdGl2ZSBwYWlyaW5nLgpUUkVFIFBhaXIgKFRSRUUgeXksIFRSRUUgeHgpCnsKICAgLy8geCAtIH54ID0geCAtICgtMSAtIHgpID0gMiAqIHggKyAxCiAgIHJldHVybiB5eSAtIH55eSA8PCB4eDsKfQoKLy8gVGhlIHNlY29uZCBjb21wb25lbnQgb2YgYSBwYWlyLgpUUkVFIFJpZ2h0IChUUkVFIHh4KQp7CiAgIHJldHVybiBsYXN0UmlnaHQgPSB4eCAlIDIgPyAwIDogMSArIFJpZ2h0ICh4eCAvIDIpOwp9CgovLyBUaGUgZmlyc3QgY29tcG9uZW50LiAgTm90ZSB0aGF0IHdlIGxlYXZlIHRoZSBvdGhlciBjb21wb25lbnQgaW4gbGFzdFJpZ2h0LgpUUkVFIExlZnQgKFRSRUUgeHgpCnsKICAgcmV0dXJuIHh4IC8gMiA+PiBSaWdodCAoeHgpOwp9CgovLyBFbmNvZGluZwovLyBQSShBLEIpID0gUGFpcigwLFBhaXIoQSxCKSkKLy8gTEFNQkRBKEEsQikgPSBQYWlyKDEsUGFpcihBLEIpKQovLyBBUFBMWShBLEIpID0gUGFpcigyLFBhaXIoQSxCKSkKLy8gU1RBUiA9IFBhaXIoMywwKSA9IDcKLy8gQk9YID0gUGFpcigzLDEpID0gMTQKLy8gVkFSKG4pID0gUGFpcig0KzJuLDApID0gOSArIDRuIFtuID49IDBdCi8vIFRoZSBlbXB0eSBjb250ZXh0IGlzIDAsIGFuZCB0aGUgY29udGV4dCBHYW1tYSxBIGlzIFBhaXIgKEEsR2FtbWEpLgovLyBTVEFSIGFuZCBCT1ggYXJlIHRoZSBvbmx5IHRlcm1zIHggd2l0aCAoeCYyKSE9MAoKLy8gSW5jcmVtZW50IHRoZSBpbmRleCBvZiBlYWNoIHZhcmlhYmxlIGluIHh4LiAgVXNlcyBTdWJzdC4KLy8gTWFraW5nIHRoaXMgYSBtYWNybyBtZWFucyB0aGF0IHdlIGNhbiBhYnNvcmIgYW4gIj0iIGFuZCBhICIoIiBpbnRvIHRoZSBtYWNyby4KI2RlZmluZSBMaWZ0KHh4KSBTdWJzdCAoNCwgMTMsIC00LCB4eCkKCi8vIFN1YnN0aXR1dGUgeXkgZm9yIHZ2IGluIHRlcm0sIGFuZCBub3JtYWxpc2UuICBWYXJpYWJsZXMgPiB5eSBnZXQgYWRqdXN0ZWQgYnkKLy8gLWNvbnRleHQuICBbVGhlIHByZWNpc2Ugbm9ybWFsaXNhdGlvbiBpczogaWYgeXkgYW5kIHRlcm0gYXJlIG5vcm1hbCwgYW5kIHRoZQovLyBzdWJzdGl0dXRpb24gaGFzIGEgbm9ybWFsIGZvcm0sIHRoZW4gdGhlIG5vcm1hbCBmb3JtIGlzIHJldHVybmVkLl0KVFJFRSBTdWJzdCAoSU5UIHZ2LCBUUkVFIHl5LCBJTlQgY29udGV4dCwgVFJFRSB0ZXJtKQp7CiAgIFRyZWUKICAgICAgYXV4ID0gTGVmdCAodGVybSksICAgICAgICAvLyBUaGUgb3BlcmF0aW9uIG9mIHRlcm0uCiAgICAgIHh4ID0gbGFzdFJpZ2h0OyAgICAgICAgICAgLy8gVGhlIGJvZHkgb2YgdGVybS4KCiAgIHsKICAgICAgcmV0dXJuCiAgICAgICAgIGF1eCAtIDIgPwogICAgICAgICBhdXggPiAyID8KICAgICAgICAgLy8gVmFyaWFibGUgb3IgU3RhciBvciBCb3guCiAgICAgICAgIGF1eCAtIHZ2ID8gdGVybSAtIChhdXggPiB2dikgKiBjb250ZXh0IDogeXkgOgogICAgICAgICAvLyBhdXggPSAwIG9yIGF1eCA9IDE6IGxhbWJkYSBvciBwaS4gIFRoZSBzdHJheSAndGVybSA9JyBiZWxvdyBpcwogICAgICAgICAvLyBoYXJtbGVzcywgYnV0IGFsbG93cyB1cyB0byBwdXNoIHRoZSAnPScgaW50byB0aGUgTGlmdCBtYWNyby4KICAgICAgICAgUGFpciAoYXV4LCBQYWlyIChTdWJzdCAodnYsIHl5LCBjb250ZXh0LCBMZWZ0ICh4eCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgIFN1YnN0ICh2disyLCB0ZXJtID0gTGlmdCAoeXkpLCBjb250ZXh0LCBSaWdodCAoeHgpKSkpCiAgICAgICAgIDoKICAgICAgICAgLy8gQXBwbGljYXRpb24uICBVc2UgQXBwbHkuCiAgICAgICAgIEFwcGx5IChTdWJzdCAodnYsIHl5LCBjb250ZXh0LCBMZWZ0ICh4eCkpLAogICAgICAgICAgICAgICAgU3Vic3QgKHZ2LCB5eSwgY29udGV4dCwgUmlnaHQgKHh4KSkpOwogICB9Cn0KCi8vIEFwcGx5IHl5IHRvIHh4IGFuZCBub3JtYWxpc2UuICBbUHJlY2lzZWx5LCBpZiB5eSBhbmQgeHggYXJlIG5vcm1hbCwgYW5kCi8vIHl5KHh4KSBpcyBub3JtYWxpc2FibGUsIEFwcGx5KHl5LHh4KSByZXR1cm5zIHRoZSBub3JtYWwgZm9ybSBvZiB5eSh4eCkuClRSRUUgQXBwbHkgKFRSRUUgeXksIFRSRUUgeHgpCnsKICAgcmV0dXJuIExlZnQgKHl5KSAtIDEKICAgICAgLy8gNSA8PCB4ID09IFBhaXIoMix4KQogICAgICA/IDUgPDwgUGFpciAoeXksIHh4KQogICAgICA6IFN1YnN0ICg0LCB4eCwgNCwgUmlnaHQgKGxhc3RSaWdodCkpOwp9CgovLyBXZSB1c2UgeHggYXMgYSBiaXQgc3RyZWFtLiAgVGhlIE1BWUJFIG1hY3JvIHRlc3RzIHRoZSBuZXh0IGJpdCBmb3IgdXMuCiNkZWZpbmUgTUFZQkUgKHh4IC89IDIpICUgMiAmJgoKLy8gRGVyaXZlIHBhcnNlcyBhIGJpdCBzdHJlYW0gaW50byB0ZXJtcyBvZiBDb0MgYW5kIG5vcm1hbGlzZXMgZXZlcnl0aGluZy4gIFRoZQovLyBvdXRwdXRzIGFyZSBhY2N1bXVsYXRlZCBpbnRvIHRoZSB2YXJpYWJsZSB5eS4gIFdlIGFsc28gcmVjdXJzZSwgc28gYXMgdG8KLy8gY292ZXIgYWxsIHRoZSBCaXRTdHJlYW1zIHdoaWNoIGFyZSA8IHh4LgpUUkVFIERlcml2ZSAoQml0U3RyZWFtIHh4KQp7CiAgIFRyZWUKICAgICAgYXV4LAogICAgICBhdXhUZXJtLAogICAgICAvLyBUaGUgYXhpb20uCiAgICAgIGNvbnRleHQgPSAwLAogICAgICB0ZXJtID0gNywKICAgICAgdHlwZSA9IDE0OwoKICAgLy8gSW5zaWRlIHRoZSB3aGlsZSBjb25kaXRpb24gaXMgdGhlIG1haW4gcmVjdXJzaW9uIHRoYXQgbWFrZXMgdXMgbW9ub3RvbmUuCiAgIC8vIEl0IGRvZXNuJ3QgbmVlZCB0byBiZSBpbnNpZGUgdGhlIHdoaWxlLCBidXQgdGhhdCBhbGxvd3MgdXMgdG8gY29tcHJlc3MgdGhlCiAgIC8vICIpLCIuICBJdCBhbHNvIG1lYW5zIHdlIGdldCBjYWxsZWQgbW9yZSBvZnRlbiwgd2hpY2ggbWFrZXMgImFjY3VtdWxhdGUiCiAgIC8vIGJpZ2dlci4uLgogICB3aGlsZSAoREVTQ0VORCAmJiBEZXJpdmUgKHh4IC0gMSksIE1BWUJFICgxKSkKCiAgICAgIC8vIEdldCBhbm90aGVyIHRlcm0uCiAgICAgIGF1eFRlcm0gPSBMZWZ0IChMZWZ0IChEZXJpdmUgKHh4KSkpLAogICAgICAgICAvLyBBbmQgZ2V0IGl0cyB0eXBlLgogICAgICAgICBhdXggPSBMZWZ0IChsYXN0UmlnaHQpLAoKICAgICAgICAgLy8gQW5kIGdldCB0aGUgbGVmdC1vdmVyIGJpdC1zdHJlYW0uICBUaGlzIGxlYXZlcyB0aGUgY29udGV4dCBmcm9tCiAgICAgICAgIC8vIHRoZSBzdWItZGVyaXZhdGlvbiBpbiBsYXN0UmlnaHQuCiAgICAgICAgIHh4ID0gTGVmdCAobGFzdFJpZ2h0KSwKCiAgICAgICAgIC8vIFJ1bGVzIHRoYXQgZGVwZW5kIG9uIHR3byBhbnRlY2VkZW50cy4uLiAgVGhlIHR3byBjb250ZXh0cyAob25lIGlzIGluCiAgICAgICAgIC8vIGxhc3RSaWdodCkgbXVzdCBiZSB0aGUgc2FtZS4KICAgICAgICAgY29udGV4dCAtIGxhc3RSaWdodCB8fCAoCiAgICAgICAgICAgIC8vIEFQUExZLiAgdHlwZSBtdXN0IGJlIFBJKGF1eCwtKS4KICAgICAgICAgICAgTGVmdCAodHlwZSkgfHwgTGVmdCAobGFzdFJpZ2h0KSAtIGF1eCB8fAogICAgICAgICAgICBNQVlCRSAodHlwZSA9IFN1YnN0ICg0LCBhdXhUZXJtLCA0LCBsYXN0UmlnaHQpLAogICAgICAgICAgICAgICAgICAgdGVybSA9IEFwcGx5ICh0ZXJtLCBhdXhUZXJtKSksCgogICAgICAgICAgICAvLyBXZWFrZW5pbmcuICBhdXhUeXBlIG11c3QgYmUgU1RBUiBvciBCT1guICBUaGUgLyAyICYgTUFZQkUKICAgICAgICAgICAgLy8gY29tYmluZXMgTUFZQkUgd2l0aCB0ZXN0aW5nIHRoZSBjb3JyZWN0IGJpdCBvZiBhdXhUeXBlLiAgSXQgaXMKICAgICAgICAgICAgLy8gc2FmZSB0byBkbyB0aGlzIGltbWVkaWF0ZWx5IGFmdGVyIGFuIEFQUExZIGFib3ZlLCBiZWNhdXNlIEFQUExZCiAgICAgICAgICAgIC8vIGRvZXMgbm90IGNoYW5nZSBjb250ZXh0cy4KICAgICAgICAgICAgYXV4IC8gMiAmIE1BWUJFICggY29udGV4dCA9IFBhaXIgKGF1eFRlcm0sIGNvbnRleHQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtID0gTGlmdCAodGVybSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBMaWZ0ICh0eXBlKSApCgogICAgICAgICAgICApLAoKICAgICAgICAgY29udGV4dCAmJiBNQVlCRSAoCiAgICAgICAgICAgIC8vIElmIHdlIGdldCBoZXJlLCB3ZSBhcmUgZWl0aGVyIGdvaW5nIHRvIGRvIFBJIGZvcm1hdGlvbiBvciBMQU1CREEKICAgICAgICAgICAgLy8gaW50cm9kdWN0aW9uLiAgUEkgZm9ybWF0aW9uIHJlcXVpcmVzIHR5cGUgdG8gYmUgU1RBUiBvciBCT1guICBXZQogICAgICAgICAgICAvLyBhbGxvdyBMQU1CREEgaW50cm9kdWN0aW9uIHdoZW5ldmVyIHRoZSBjb250ZXh0IGlzIG5vbi1lbXB0eS4KICAgICAgICAgICAgLy8gVGhpcyBleHRlbnNpb24gaXMgYSBjb25zZXJ2YXRpdmUgZXh0ZW5zaW9uIG9mIENvQy4KICAgICAgICAgICAgdGVybSA9IFBhaXIgKAogICAgICAgICAgICAgICAvLyBCZWNhdXNlIG9mIHRoZSAmJiBpbiBNQVlCRSwgdGhpcyBzdWJleHByZXNzaW9uIHJldHVybnMgYQogICAgICAgICAgICAgICAvLyBib29sZWFuIDEgaWYgd2UncmUgZG9pbmcgTEFNQkRBIGludHJvZHVjdGlvbiwgMCBpZiB3ZSdyZQogICAgICAgICAgICAgICAvLyBkb2luZyBQSSBmb3JtYXRpb24uICBUaGUgfnR5cGUmMnwgZW5zdXJlcyB0aGF0IHdlIGRvIExBTUJEQQogICAgICAgICAgICAgICAvLyBpbnRyb2R1Y3Rpb24gaWYgdHlwZSBpcyBub3QgdGhlIFN0YXIgb3IgQm94IG5lZWRlZCB0byBkbyBQSQogICAgICAgICAgICAgICAvLyBmb3JtYXRpb24uCiAgICAgICAgICAgICAgIH50eXBlICYgMiB8IE1BWUJFICgKICAgICAgICAgICAgICAgICAgLy8gSWYgd2UncmUgZG9pbmcgbGFtYmRhIGludHJvZHVjdGlvbiBvbiB0ZXJtLCB0aGVuIHdlIGFsc28KICAgICAgICAgICAgICAgICAgLy8gbmVlZCB0byBkbyBhIFBJIGZvcm1hdGlvbiBvbiB0eXBlLiAgVGhpcyBpcyBhbHdheXMKICAgICAgICAgICAgICAgICAgLy8gbm9uLXplcm8uICAxIDw8IHggPSBQYWlyKDAseCkuCiAgICAgICAgICAgICAgICAgIHR5cGUgPSAxIDw8IFBhaXIgKExlZnQgKGNvbnRleHQpLCB0eXBlKSksCiAgICAgICAgICAgICAgIFBhaXIgKExlZnQgKGNvbnRleHQpLCB0ZXJtKSksCgogICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGNvbnRleHQgaXRlbSB3ZSBqdXN0IHVzZWQuCiAgICAgICAgICAgIGNvbnRleHQgPSBsYXN0UmlnaHQgKSwKCiAgICAgICAgIC8vIElmIHR5cGUgaXMgU1RBUiBvciBCT1ggdGhlbiB3ZSBhbGxvdyB2YXJpYWJsZSBpbnRyb2R1Y3Rpb24uCiAgICAgICAgIHR5cGUgLyAyICYgTUFZQkUgKAogICAgICAgICAgICBjb250ZXh0ID0gUGFpciAodGVybSwgY29udGV4dCksCiAgICAgICAgICAgIHR5cGUgPSBMaWZ0ICh0ZXJtKSwKICAgICAgICAgICAgdGVybSA9IDkgKTsgICAgIC8vIFBhaXIgKDQsIDApCiAgIHsKICAgICAgLy8gUGFpciB0ZXJtLCB0eXBlLCBjb250ZXh0LCBhbmQgeHggdG9nZXRoZXIsIGFuZCBjaHVjayBpdCBhbGwgb250bwogICAgICAvLyBhY2N1bXVsYXRlLgogICAgICByZXR1cm4gYWNjdW11bGF0ZSA9IFBhaXIgKFBhaXIgKHRlcm0sIFBhaXIgKHR5cGUsIFBhaXIgKHh4LCBjb250ZXh0KSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY3VtdWxhdGUpOwogICB9Cn0KClRSRUUgbWFpbiAoKQp7CiAgIHJldHVybiBEZXJpdmUgKDIpOwp9