|
SimpleLazyFirstOrderLanguage
The language dealt with by the Small Positive Supercompiler.
Featured The Language the supercompiler deals withA Simple Lazy First-Order Language (SLL)Our supercompiler deals with programs written in a simple first-order functional language (SLL). The intended operational semantics of the language is normal-order graph reduction to weak head normal form. The lexical structure of SLLConstructor names, function names and variables are represented by identifiers. An identifier is a sequence of latin letters and digits, the first character being a letter. A function name or a variable must start with a small letter. A constructor name must start with a capital letter. The syntax of programsIn the following {A} means the construct A repeated zero or more times, and [A] means the construct A is optional. program ::= {functionDefinition} functionDefinition ::= fFunctionDefinition | gFunctionDefinition fFunctionDefinition ::= fRule; gFunctionDefinition ::= {gRule;} fRule ::= functionName(fParameters) = expression gRule ::= functionName(gParameters) = expression fParameters ::= [variable {, variable}] gParameters ::= pattern {, variable} pattern ::= constructorName([variable {, variable}]) expression ::= variable | constructor | fFunctionCall | gFunctionCall constructor ::= constructorName[([expression {, expression}])] fFunctionCall ::= functionName([expression {, expression}]) gFunctionCall ::= functionName(expression {, expression}) We require that no two patterns in a g-function definition contain the same constructor c, that no variable occur more than once in a left side of a rule, and that all variables on the right side of a rule be present in its left side. In a program, all occurrences of a constructor, an f-function or a g-function must have the same arity. Note that if a constructor is a zero-arity one the parentheses can be omitted: B() and B are equivalent. ExamplesAppending listsIn the following program, the g-function Append appends 2 lists, and the f-function Append3 appends 3 lists. append(Nil, vs) = vs; append(Cons(u, us), vs) = Cons(u, append(us, vs)); append3(xs, ys, zs) = append(append(xs, ys), zs); Testing natural numbers for equalitySupposing that the natural numbers are represented in unary system (Z represents zero, and S(n) the number n+1), the function eq tests numbers for equality. eq(Z, y) = eqZ(y); eq(S(x), y) = eqS(y, x); eqZ(Z) = True; eqZ(S(x)) = False; eqS(Z, x) = False; eqS(S(y), x) = eq(x, y); Note that SLL doesn't allow rules like eq(S(x), S(y)) = eq(x, y); A program that exploits the lazyness of SLLThe following program defines the function member(x, ys) that tests that the number x appears in the list ys. eq(Z, y) = eqZ(y); eq(S(x), y) = eqS(y, x); eqZ(Z) = True; eqZ(S(x)) = False; eqS(Z, x) = False; eqS(S(y), x) = eq(x, y); null(Nil) = True; null(Cons(x, xs)) = False; head(Cons(x, xs)) = x; tail(Cons(x, xs)) = xs; if(True, x, y) = x; if(False, x, y) = y; not(x) = if(x, False, True); or(x, y) = if(x, True, y); and(x, y) = if(x, y, False); member(x, list) = and(not(null(list)), or(eq(x, head(list)), member(x, tail(list)))); NotesCalls to undefined functionsAs strange as it may seem, a program is allowed to contain calls to undefined functions, on condition that all calls to an undefined function have the same arity. RationalePartial process tree may have a leaf with label g(C(...), ...), despite the fact that there is no rule in the definition of g corresponding to c. This means that an attempt to evaluate such a call would result in abnormal program termination. However, since the semantics of the language is lazy, such a call may never be evaluated. For this reason spsc sometimes generates calls to g-functions whose domain is empty. Technically, a definition of such a function has zero rules. |