#ifndef __StdLib__

#define false []
#define true  [[]]
#define zero  []
#define one   [[]]

#define pos0(X) hd(X)
#define pos1(X) hd(tl(X))
#define pos2(X) hd(tl(tl(X)))

#define Push(x,Stack) Stack = x . Stack
#define Pop(X,Stack) X = hd Stack; Stack = tl Stack

#define IfThenElse(exp,ifBranch,elseBranch)\
Push(StdLibITE0,StdLibStack); Push(StdLibITE1,StdLibStack);\
StdLibITE0 = exp;\
StdLibITE1 = true;\
while StdLibITE0 do {\
  StdLibITE0 = false;\
  StdLibITE1 = false;\
  ifBranch\
};\
while StdLibITE1 do {\
  StdLibITE1 = false;\
  elseBranch\
};\
Pop(StdLibITE1,StdLibStack); Pop(StdLibITE0,StdLibStack)

#define IfThen(exp,body) IfThenElse(exp,body,X=X)

/* Result := "X==Y" */
#define Equal(X,Y,Result)\
StdLibX = X . [];\
StdLibY = Y . [];\
Result = true;\
while StdLibX do {\
  IfThenElse(hd StdLibX,\
  /* then */ IfThenElse(hd StdLibY,\
             /* then */ StdLibX= (hd (hd StdLibX)) . \
                         ((tl (hd StdLibX)) . (tl StdLibX));\
      			StdLibY= (hd (hd StdLibY)) . \
                         ((tl (hd StdLibY)) . (tl StdLibY)),\
             /* else */ Result= false;\
                        StdLibX = []),\
  /* else */ IfThenElse(hd StdLibY,\
             /* then */ Result= false;\
                        StdLibX= [],\
             /* else */	StdLibX= tl StdLibX;\
                        StdLibY= tl StdLibY))\
}

#define Inc(X) X= [] . X
#define Dec(X) X= tl X

/* Value := array[index] */
#define Lookup(index,array,Value)\
StdLibX= array; StdLibY= index;\
while StdLibY do { Dec(StdLibX); Dec(StdLibY) };\
Value= hd StdLibX

/* Array[index] := value */
#define Update(index,Array,value)\
StdLibX= index; StdLibY= [];\
while StdLibX do {\
  StdLibY= (hd Array) . StdLibY;\
  Dec(Array); Dec(StdLibX)\
};\
Array= (value) . (tl Array);\
while StdLibY do {\
  Array= (hd StdLibY) . Array;\
  Dec(StdLibY)\
}

/* Y := append(reverse(X),Y), X := [] */
#define Flush(X,Y) while X do { Y= (hd X) . Y; Dec(X) }

#define __StdLib__
#endif
