Syntax of Indexicals

X ::= variable { domain variable }

Constant ::= integer
| inf { minus infinity }
| sup { plus infinity }

Term ::= Constant
| X { suspend until assigned }
| min(X) { min. of domain of X }
| max(X) { max. of domain of X }
| card(X) { size of domain of X }
| - Term
| Term + Term
| Term - Term
| Term * Term
| Term /> Term { division rounded up }
| Term /< Term { division rounded down }
| Term mod Term

TermSet ::= {Term,...,Term}

Range ::= TermSet
| dom(X) { domain of X }
| Term .. Term { interval }
| Range /\ Range { intersection }
| Range \/ Range { union }
| \ Range { complement }
| - Range { pointwise negation }
| Range + Range { pointwise addition }
| Range - Range { pointwise subtraction }
| Range mod Range { pointwise modulo }
| Range + Term { pointwise addition }
| Range - Term { pointwise subtraction }
| Term - Range { pointwise subtraction }
| Range mod Term { pointwise modulo }
| Range ? Range
| unionof(X,Range,Range)
| switch(Term,MapList)

ConstantSet ::= {integer,...,integer}

ConstantRange ::= ConstantSet
| Constant .. Constant
| ConstantRange /\ ConstantRange
| ConstantRange \/ ConstantRange
| \ ConstantRange

MapList ::= []
| [integer-ConstantRange|MapList]

CList ::= []
| [integer|CList]

Indexical ::= X in Range

Indexicals ::= Indexical
| Indexical , Indexicals

ConstraintBody ::= Indexicals
| LinExpr RelOp LinExpr
| element(X,CList,X)
| relation(X,MapList,X)

Head ::= term { a compound term with unique variable args }

TellPos ::= Head +: ConstraintBody
TellNeg ::= Head -: ConstraintBody
AskPos ::= Head +? Indexical
AskNeg ::= Head -? Indexical

ConstraintDef ::= TellPos.
?(TellNeg.)
?(AskPos.)
?(AskNeg.)