Content uploaded by Christoph Walther
Author content
All content in this area was uploaded by Christoph Walther on Jul 13, 2020
Content may be subject to copyright.
Content uploaded by Christoph Walther
Author content
All content in this area was uploaded by Christoph Walther on Jul 13, 2020
Content may be subject to copyright.
The L1.0Primer
Christoph Walther
Markus Aderhold
Andreas Schlosser
Fachgebiet Programmiermethodik
Fachbereich Informatik
Technische Universit¨at Darmstadt
http://verifun.org
verifun@informatik.tu-darmstadt.de
Technical Report VFR 06/01
April 4, 2006 (Update June 10, 2006)
Abstract
This document defines syntax and semantics of the functional programming language L(version
1.0)whichisusedinXeriFun 3.0 [Ver] for writing programs and stating lemmas about them.
The use of Lis illustrated by several examples and a small case study.
Contents
1 Preface 3
2SyntaxofL4
2.1 DataStructures..................................... 4
2.1.1 Definitions ................................... 4
2.1.2 TypesandTerms................................ 5
2.1.3 FixityDeclarations............................... 7
2.2 Procedures ....................................... 9
2.2.1 Definitions ................................... 9
2.2.2 Let-Expressions................................. 11
2.2.3 Incompletely DefinedProcedures....................... 12
2.3 Lemmas ......................................... 13
2.3.1 Definitions ................................... 13
2.3.2 Connectives................................... 14
3 Semantics of L16
3.1 SemanticsofDataStructuresandProcedures.................... 16
3.1.1 TheExceptionGuard ............................. 16
3.1.2 TheComputationCalculus .......................... 17
3.1.3 The Interpreter evalP............................. 19
3.1.4 Termination of L-Programs .......................... 20
3.2 SemanticsofLemmas ................................. 22
3.3 DomainProcedures................................... 22
4 The Tautology Checker - A Case Study 25
4.1 Preliminaries ...................................... 25
4.2 TheTautologyCheckingProcedure.......................... 26
4.3 SoundnessoftheTautologyCheckingProcedure .................. 28
4.4 CompletenessoftheTautologyCheckingProcedure................. 29
5Appendix 30
5.1 CharacterSet...................................... 30
5.2 NameSpaces ...................................... 30
5.3 NamingConventions.................................. 30
5.4 ReservedWordsandSymbols ............................. 31
5.5 SeparationofSymbols ................................. 31
5.6 Predefined and Implicitly DefinedProceduresandLemmas ............ 31
5.7 Aliases.......................................... 32
1
Index 35
Bibliography 35
2
1. Preface
This document describes the functional programming language L(version 1.0) which is used
in the verification tool XeriFun 3.0 [Ver] for writing programs and stating lemmas about them.
The development of Lis not meant as an attempt to invent just another programming language.
There are no features in Lwhich cannot be found in other languages, and worse, many useful
feature of these languages are (still) missing.
In fact, the intention at the beginning of the development was not to define a program-
ming language. It rather was the need for a simple notation to state propositions about data
structures and procedures in order to investigate reasoning problems arising when proving these
propositions by machine. Since the reasoning problems had been the focus of attention, not
much care was given to the notation, which grew up rather rampantly taking the notation used
in the former inka system [BHHW86] as a starting point.
The development of XeriFun started as a small student project but grew up more successfully
than anticipated. New language features were needed to write up more ambitious case studies in
order to challenge the verifier. It was a rather obvious choice to incorporate features well known
from programming languages. But when we noticed that we were defining our own functional
language, it was too late to switch over to a “real” programming language. Simply too much time
hadbeenspenttodeveloptheverifier and to build a lot of software. This makes it impossible in
an academic environment to restart from scratch to reimplement the whole system for another
language. This might apologize why we came up with a further programming language and also
answers the question “Why don’t you use a ’real’ functional language” sometimes heard.
But there is another point: Since our concern is verification, it does not help to use a “real”
language containing features the verifier does not support. This would rather mean to define
subsets of the “real” language by restricting it to language features the verifier can cope with.
But it takes time to set up a verifier to support all these beautiful language features coming
with “real” functional languages. So this answers another question sometimes heard: “Why
does your language not support mutual recursion, higher-order functions, a more flexible type
system, etc.?” This is simply because we first have to develop the reasoning mechanisms for a
feature before we can integrate it into the language. And the development of those mechanisms
requires numerous experiments and tests, unfortunately always taking much more time than
expected.
Having extended our “notation” from time to time with the development of the XeriFun
system, we felt that the time was ripe to give it a name and–more importantly–to present the
formal definition for it. So in the sequel, we define syntax and semantics of L,tryingtobeas
brief as possible but as precise as necessary. We also illustrate the use of Lby several examples
and present a small case study which–as we hope–helps to become quickly familiar with the
language.
3
2. Syntax of L
2.1. Data Structures
2.1.1. Definitions
Adata structure is defined by an L-expression of form
structure struct[@V1,...,@Vl]<=con s 1(sel1,1:type1,1,...,sel1,n1:type1,n1)
...
con s k(selk,1:typek,1,...,sel k,nk:typek,nk)
(2.1)
where l≥0, k≥1andni≥0foreachi∈{1,...,k}.Thesymbolstruct is called a type
constructor of arity land the symbols @V1,...,@Vlare called type variables.
The L-expression (2.1) defines a type struct[@V1,...,@Vl] and must satisfy for each i∈
{1,...,k}and each h∈{1,...,n
i}:
•typei,h is a type built by the type variables @V1,...,@Vl,typestruct [@V1,...,@Vl]
and the type constructors (different from the predefined type bool –see Example 1) defined
previously by other data structures,
•the symbols struct,co ns iand sel i,h are pairwise different as well as different from all
identifiers that have been previously introduced by data structure, procedure and lemma
definitions.
In addition,
•each type variable @Vjis used in one of the types typei,h different from struct [@V1,...,@Vl]
for some i∈{1,...,k}and some h∈{1,...,n
i}at least, and
•typei,h 6=struct[@V1,...,@Vl] must hold for some i∈{1,...,k}and each h∈{1,...,n
i}.
One writes simply con s iinstead of cons i() if ni= 0 as well as structure struct <=...
instead of structure struct []<=... if l=0. struct is called a monomorphic type in such a
case, and struct[@V1,...,@Vl]isapolymorphic type otherwise.
Example 1.
1. The monomorphic type bool is defined by the L-expression
structure bool <=true,false .
This data structure is predefined in L.
4
2. The monomorphic type Nis defined by the L-expression
structure N<=0,+(−:N).
This data structure–defining the natural numbers IN –is predefined in L. The constructor
function symbol +(denoting the successor function) can be alternatively written as succ,
the selector function symbol −(denoting the predecessor function) can be alternatively
written as pred and the type Ncan be alternatively written as nat.1
3. The polymorphic type SEXPR [@ITEM ]is defined by the L-expression
structure SEXPR [@ITEM ]<=
NIL,
ATOM (DATA :@ITEM ),
CONS(CAR :SEXPR [@ITEM ],CDR :SEXPR [@ITEM ]) .
This data structure (related to the s-expressions of Lisp)defines binary trees which hold
their data in the leaves.
4. The polymorphic type LIST [@ITEM ]is defined by the L-expression
structure LIST [@ITEM ]<=
EMPTY ,
ADD(HD :@ITEM ,TL :LIST [@ITEM ]) .
This data structure defines linear lists, where EMPTY stands for the empty list and ADD
builds a new list kby placing some new list element HD(k)in front of another list TL(k).
5. The polymorphic type tree [@ITEM ]is defined by the L-expression
structure tree [@ITEM ]<=
leaf (data :@ITEM ),
node(descendants :LIST [tree [@ITEM ]]) .
This data structure defines finitely branching trees the inner nodes of which may have
different outdegrees and the leaves hold the data. ¥
2.1.2. Types and Terms
Types are built with type constructors and type variables, where the arity of the type construc-
tors has to be respected. A type containing type variables is called polymorphic,andother-
wisethetypeismonomorphic. By replacing type variables in a polymorphic type by types,
further types are obtained. So, for the data structure definitions of Example 1, SEXPR [N],
LIST [N], LIST [SEXPR [N]] and SEXPR [LIST [N]] are monomorphic types, and the types
SEXPR [SEXPR [@ITEM ]] and LIST [LIST [@ITEM ]] are polymorphic. However, when build-
ing further types, type variables must not be replaced by the type bool ,soe.g. SEXPR [bool ]
and LIST [bool ] are no legal types.2
Each data structure definition DS as given in (2.1) defines a signature in terms of types for
the function symbols introduced by DS :Foreachi∈{1,...,k}and each h∈{1,...,n
i}:
1Note that “:” always has to be enclosed in blanks in a type declaration of a selector.
2Type boo l receives special treatment as function symbols p:τ1×...×τn→bool adopt the rˆole of predicate
symbols in L.
5
•con s i:typei,1×... ×typei,ni→struct [@V1,...,@Vl], called a constructor function
symbol,
•?consi:struct [@V1,...,@Vl]→boo l , called a structure predicate symbol, and
•seli,nh:struct[@V1,...,@Vl]→typei,nh, called a selector function symbol.
Using this signature, terms tcan be defined and assigned a type τ(denoted t:τfor short)
as usual (see e.g. [CW85]). For example,
•true and false are terms of type bool ,
•0, +(0), +(+(0)), +(−(0)), −(+(0)), +(+(+(0))) are terms of type N,
•CONS(NIL,NIL), CONS (NIL,CONS (NIL,NIL)) are terms of type SEXPR [@ITEM ],
and
•CONS(NIL,NIL), CONS (NIL,ATOM (+(0))), CONS (CONS (NIL,ATO M (−(0))),NIL)are
terms of type SEXPR [N].
OnemayalsousenumeralstowritetermsoftypeN,wherenstands for napplications of +
to 0. So e.g., 1 stands for +(0), 2 for +(+(0)), 3 for +(+(+(0))) etc.
For building terms, the following function symbols are available in addition for each type τ
different from a type variable:
•=:τ×τ→bool ,whereτ6=bool ,
•if :bool ×τ×τ→τ,and
•cas e :τ0×τ×...×τ
|{z }
ktimes
→τ,whereτ0is some type defined by a data structure with k
constructors.
The symbol =denotes equality and is written in infixnotation.
Boolean conditionals (also called if -expressions) of type τare written in functional or in
procedural notation,viz.
•if {a, b, c},or
•if athen belse cend if .
Structural conditionals (also called cas e -expressions) of type τdefined by a data structure
with constructors con s 1,...,cons kare written in functional or in procedural notation,viz.
•cas e {t;cons 0
1:t1, ... , con s 0
k:tk},
•cas e {t;cons 0
1:t1, ... , con s 0
h:th,other:t0},
•case tof cons0
1:t1, ... , con s 0
k:tkend cas e ,or
•case tof cons0
1:t1, ... , con s 0
h:th,other :t0end cas e ,3
where {con s 0
1,...,con s 0
k}={con s 1,...,cons k}and {co ns 0
1,...,con s 0
h}Ã{con s 1,...,cons k}.
Instead of end if or end cas e ,end as well as pairs of parentheses instead of pairs of curly
brackets may be used when writing conditional expressions in functional notation.
3Note that “:” always has to be enclosed in blanks in a ca se -expression.
6
2.1.3. Fixity Declarations
Each function symbol in a data structure definition of form (2.1) may be preceded by a fixity
declaration of form
•[prefix],
•[postfix],
•[outfix],
•[infix],
•[infixl,N],or
•[infixr,N ]
where N, called the precedence of the function symbol, is a numeral different from 0.
prefixand post fix
Fixity prefixis assumed by default if a fixity declaration is missing and fixity postfixplaces a
function symbol behind the list of arguments, i.e. (...)!for a postfixfunction symbol !as
compared to !(...)if!is declared prefixor no fixity is declared for !at all.
Constant symbols cannot have a fixity other than prefix. Also structure predicates ?cons
have always fixity prefix, except if the constructor cons has fixity outfix(see below).
outfix
If fixity outfixis declared, 2 function symbols (not defined elsewhere) separated by a colon
(enclosed in blanks) may (but need not) be used. For example, one may write
structure bintree [@ITEM ]<=
⊥,
[outfix]l:m(left :bintree [@ITEM ],key :@ITEM ,right :bintree [@ITEM ]) .
and terms of type bintree [N]thenarewrittenas
•l⊥,0,⊥m,
•ll⊥,0,⊥m,1,⊥m,
•ll⊥,5,⊥m,1,l⊥,3,⊥mmetc.4
Afixity declaration of form “[outfix]symbol” is treated like “[outfix]symbol :symbol”. So if
one replaces “[outfix]l:m”by“[outfix]|”intheabovedefinition, terms of type bintree [N]are
written as
•|⊥,0,⊥|,
•||⊥,0,⊥|,1,⊥|,
4Note that the argument list of an outfixfunction symbol always has to be enclosed in blanks.
7
•||⊥,5,⊥|,1,|⊥,3,⊥||etc.
Theapplicationofastructurepredicate of a constructor “[outfix]left :right ”toanargument
tis written as “?left tright”. So one writes e.g. ?ltmfor the constructor of bintree.In
cas e -expressions, one writes “left right” for those constructors, for example
case tof ⊥:... , lm:... end case .
infix,infixr and infixl
These fixity declarations are reserved for binary function symbols. One may define, for example,
structure SEXPR [@ITEM ]<=
NIL,
ATOM (DATA :@ITEM ),
[infix]◦(CAR :SEXPR [@ITEM ],CDR :SEXPR [@ITEM ])
and terms of type SEXPR [N] then are written as
•(NIL ◦NIL),
•(NIL ◦ATO M (1)),
•((NIL ◦ATOM (1)) ◦NIL)etc.,
where “◦” has to be enclosed in blanks. If one replaces [infix]by[infixl ,2]intheabovedefinition,
parenthesesmaybeomittedinleft-nested◦-terms. For instance, terms of type SEXPR [N]now
can (but need not) be written as
•NIL ◦NIL,
•NIL ◦ATOM (1),
•NIL ◦ATOM (1) ◦NIL
where the latter term is the same as
•((NIL ◦ATOM (1)) ◦NIL)
hence different to
•(NIL ◦(ATOM (1) ◦NIL)).
The precedence of a function symbol, e.g. 2 for the constructor ◦in the example, is used to
resolve ambiguities. A term a♦b¤cstands for (a♦b)¤c,iftheinfixl function symbol ♦
has a greater precedence than the infixl function symbol ¤,anditstandsfora♦(b¤c)if
theprecedenceof¤is greater than the precedence of ♦.Ifbothfunctionsymbolshavesame
precedence, a♦b¤cis not a syntactically correct term, hence parentheses must be used to
resolve ambiguities explicitly.
Similarly, infixr is used to omit parentheses in terms which then are treated as right-nested.
Further examples:
8
Example 2.
1. The polymorphic type pair [@ITEM1 ,@ITEM2 ]is defined by the L-expression
structure pair [@ITEM1,@ITEM2]<=
[infix] •([postfix] 1: @ITEM1, [postfix] 2:@ITEM2)
and
−(2 •3) is a term of type pair [N,N],
−(1 •(2 •3)) is a term of type pair [N,pair [N,N]],
−((1 •2) •3) is a term of type pai r [pair [N,N],N],
−(1 •(2 •3))1is a term of type N,and
−(1 •(2 •3))2is a term of type pair [N,N].
2. The polymorphic type list [@ITEM ]is defined by the L-expression
structure list [@ITEM]<=
ø,[infixr,100] ::(hd : @ITEM, tl : list[@ITEM])
and
−1::2::3::4::øisatermoftypelist [N],
−(1 •2) :: (3 •4) :: øisatermoftypelist [pair [N,N]],and
−(1 :: 2 :: ø):: (3 :: 4 :: ø)::øisatermoftypelist [list [N]].¥
2.2. Procedures
2.2.1. Definitions
Aprocedure is defined by an L-expression of form
function proc(x1:type1,...,x
k:typek):type <=body proc (2.2)
where k≥1andforeachi, j ∈{1,...,k}:
•proc, called the name of the procedure, is an identifier different from all identifiers that
have been previously introduced by data structure, procedure and lemma definitions,
•xiis a symbol different from all type constructors and function symbols of the data struc-
ture and procedure definitions introduced so far,
•xi6=xj,ifi6=j,
•typeiis a type variable or a type built with type constructors different from bool defined
previously by some data structures,
•type is a type variable or a type built with type constructors definedpreviouslybysome
data structures, and
9
•each type variable in type also appears in some of the types typei.
A procedure definition as given in (2.2) extends the signature by a
•procedure function symbol proc :typei×...×typek→type.
The symbols xiin (2.2) are called the formal parameters of procedure proc and are used as
variable symbols of type typei. The expression bod y proc is called the body of procedure proc and
it is demanded that
•body proc is a term of type type using only
−function symbols of the data structure and procedure definitions introduced so far,
−the procedure function symbol proc,and
−the formal parameters xi, such that
•thetypeofeachactual parameter tiis identical to typeifor each occurrence of proc(t1,...,t
k)
in body proc,and
•bis free of if -andca se -expressions for each subterm if {b, . . .}or ca se {b;...}of bod y proc .
Like for constructor and selector function symbols in a data structure definition, the pro-
cedure function symbol may be preceded by a fixity declaration in the head of the procedure
definition, cf. Section 2.1.3. Also formal parameters sharing a common type may be written as
x1,...,x
k:type instead of x1:type,...,x
k:type intheprocedurehead.
Example 3.
1. The greater-than relation on natural numbers can be defined by the procedure
function [infixl,1] >(x : N,y: N):bool<=
if ?0(x) then false else if ?0(y) then true else −(x) >−(y) end if end if .
Procedure >is predefined in L.5
2. Addition of natural numbers can be defined by the procedure
function [infixr,10] +(x, y : N): N<=
if ?0(x) then yelse +(−(x) + y) end .
3. Multiplication of natural numbers can be defined by the procedure
function [infixr,20] ∗(x, y : N): N<=
if ?0(x) then 0else −(x) ∗y+yend .
4. The factorial function can be defined by the procedure
function [postfix] !(x : N): N<=
if ?0(x) then 1else (−(x))!∗xend .
5Note that “:” always has to be enclosed in blanks in a type declaration of a formal parameter.
10
5. List concatenation can be defined by the procedure
function [infixr,10] <>(k, l : list[@ITEM]) : list[@ITEM]<=
if ?ø(k) then lelse hd(k) :: (tl(k) <> l) end .
6. Thelengthofalistcanbecomputedbytheprocedure
function [outfix] |(k : list[@ITEM]): N<=
if ?ø(k) then 0else +(|tl(k) |)end .
7. Deletion of list elements can be defined by the procedure
function [infixr,100] \(k : list[@ITEM], i : @ITEM) : list[@ITEM] <=
if ?ø(k)
then ø
else if i=hd(k)then tl(k) else hd(k) :: (tl(k) \i) end
end .
8. The product of the members of a list of natural numbers can be defined by the procedure
function Π(k : list[N]): N<=
if ?ø(k) then 1else hd(k) ∗Π(tl(k)) end .¥
2.2.2. Let-Expressions
Procedure bodies may contain so-called let-expressions, i.e. expressions of the form
let var := tin rend let
where
•var is some identifier–called a local variable–which is different from the formal para-
meters of the procedure and from all type constructors and function symbols of the data
structure and procedure definitions introduced so far, and
•risatermwhichmayalsocontainvar and other local variables introduced by further
let-expressions surrounding the let-expression in the procedure body.
The local variable var of a let-expression is assigned the type of term tand the whole let-
expression is assigned the type of term r. Instead of procedural notation,let -expressions may
also be written in functional notation ,viz.
•let{var := t;r}.
Instead of end let,end as well as pairs of parentheses instead of pairs of curly brackets may
be used when writing let-expressions in functional notation.
11
Example 4.
1. The depth of binary trees represented by terms of type SEXPR [@ITEM ]can be computed
by the procedure
function depth(x : SEXPR [@ITEM ]): N<=
case xof
CONS : let CAR-depth := depth(CAR(x)) in
let CDR-depth := depth(CDR(x)) in
if CAR-depth >CDR-depth then +(CAR-depth) else +(CDR-depth) end
end let
end let ,
other :0
end case .
2. The minimal element of a list of natural numbers can be defined by the procedure
function minimum(k : list [N]): N<=
if ?ø(k)
then 0
else if ?ø(tl(k))
then hd(k)
else let min-tl := minimum(tl(k)) in
if hd(k) >min-tl then min-tl else hd(k) end if
end let
end if
end if .¥
2.2.3. Incompletely Defined Procedures
For some procedures, a meaningful result cannot be defined for certain inputs or it is impossible
to stipulate a result for certain inputs at all. For example, it is not meaningful to define the
minimum of an empty list as done by procedure minimum of Example 4. And worse, one cannot
give a procedure for computing the last element of a polymorphic list as no result can be defined
for the empty list.
As a remedy, the wildcard symbol may be used to denote an unspecified result in a pro-
cedure body by writing in the alternatives of a conditional, yielding a incompletely defined
procedure. Incompletely defined procedures (also known as loose specifications or underspecifi-
cations in the literature) are in particular useful to avoid artificial results using “default” values
in case of invalid inputs, see [WS05b] for further details. For instance, 0 may be replaced in
procedure minimum of Example 4 by . Further examples:
12
Example 5.
1. Subtraction of natural numbers can be defined by the procedure
function [infixl,10] −(x, y : N): N<=
if ?0(y) then xelse if ?0(x)thenelse −(x) −−(y) end end .
2. Truncated division of natural numbers can be defined by the procedure
function [infixl,20] /(x, y : N): N<=
if ?0(y) then else if y>xthen 0else +((x −y) /y) end end .
3. The remainder function for natural numbers can be defined by the procedure
function [infixr,20] mod(x, y : N):N<=
if ?0(y) then else if y>xthen xelse (x −y) mod y end end .
4. The last element of a non-empty polymorphic list can be defined by the procedure
function last(k : list [@ITEM]): @ITEM<=
if ?ø(k)
then
else if ?ø(tl(k)) then hd(k) else last(tl(k)) end
end .¥
2.3. Lemmas
2.3.1. Definitions
Alemma is defined by an L-expression of form
lemma lem <=∀x1:type1, ... , x
k:typekbody lem (2.3)
where k≥0andforeachi, j ∈{1,...,k}:
•lem–called the name of the lemma–is an identifier different from all identifiers that have
been previously introduced by data structure, procedure and lemma definitions,
•xiis an identifier–called a variable of the lemma–different from all identifiers denoting
type constructors and function symbols of the data structure and procedure definitions
introduced so far,
•xi6=xj,ifi6=j,
•typeiis an identifier denoting a type variable or a type built with type constructors different
from bool defined previously by some data structures, and
13
•body lem –called the body of the lemma–is a term of type bool using only
−the lemma variables xiof type typei,and
−the function symbols of the data structure and procedure definitions introduced so far.
Like in procedure definitions, the variables of a lemma sharing a common type may be written
as x1,...,x
k:type instead of x1:type,...,x
k:type in a lemma definition. Also let -expressions may
be used in the lemma body, cf. Section 2.2, where, however, the local variables must be different
from the variables of the lemma. The universal quantifier “∀” may be written alternatively as
“all ” and is omitted if k=0.
2.3.2. Connectives
The following table illustrates how the usual connectives are represented by the constants true
and false and the boolean conditional if ,whereaand bstand for boolean terms in the table:
Connective Boolean Term
¬aif {a, false,true }
a∨bif {a, true,b}
a∧bif {a, b, false}
a→bif {a, b, true}
a↔bif {a, b, if {b, false,true }}
¬a∧bif {a, false,b}
Instead of writing if {a, false,true}to denote the negated boolean term a, the negation operators
¬or not may be used, i.e. ¬aor not amay be written alternatively.
Example 6.
1. The following lemma states facts about the minimal element a list of natural numbers:
lemma minsort sorts-lemma#1 <=∀k : list[N], n : N
if {?ø(k),
true,
if {n>hd(k),
let{min-k := minimum(k);
if {min-k = n,
true,
if {min-k = hd(k),
¬min-k >minimum(n :: tl(k)),
¬min-k >minimum(hd(k) :: (tl(k) \min-k))}}},
let{min-k := minimum(n :: tl(k));
if {min-k = n, ¬min-k >minimum(k), true}}}} .
2. Associativity of + is stated by the lemma
lemma +associative<=∀x, y, z : N(x+y)+z=x+y+z .
14
3. Distributivity of + and ∗is stated by the lemma
lemma ∗distributes over + <=∀x, y, z : N
if {(x + y) ∗z=x∗z+y∗z, x ∗(y + z) = x ∗y+x∗z, false }.
15
3. Semantics of L
Here we present a brief account on the semantics of Land refer to [Sch06] for details.
3.1. Semantics of Data Structures and Procedures
We define an operational semantics for L, thus providing a meaning for the expressions of the
language: Given an L-program Pas a list of data structure and procedure definitions, we write
G(P)τfor the set of ground terms of a monomorphic type τin Pbuilt with the function symbols
introduced by the data structure and procedure definitions of P,andweletC(P)τdenote the
set of constructor ground terms of a monomorphic type τin P, i.e. those terms of G(P)τwhich
contain constructor function symbols only.
The elements of C(P):=SτC(P)τdenote the set of all values given for the program Pand
the elements of G(P):=SτG(P)τdenote the set of all expressions for which values shall be
computed by the procedures of P. Such computations are formally defined by a partial mapping
evalP:G(P)7→G(P)
which assigns the result evalP(t)∈G(P) computed for a term t∈G(P)tothisterm. The
mapping evalPis called the interpreter of the L-program P.
Since Pmay contain non-terminating procedures, cf. Section 3.1.4, evalPis a partial map-
ping only, which means that evalP(t) may not exist for some program Pand some term t∈G(P).
Wesayinsuchacase,thatthecomputationoftdiverges and write evalP(t)=⊥for denoting
divergence. Otherwise, either evalP(t)∈C(P), called a succeeding computation of t, because a
value is obtained for t,orevalP(t)∈G(P)\C(P) else, which means that the computation of t
has failed.TheresultevalP(t) is called a stuck computation of tin such a case.
3.1.1. The Exception Guard
To care for the computation of calls of incompletely defined procedures, cf. Section 2.2.3, a
so-called ex cept ion g uard ex cept proc is associated with each procedure proc as defined in (2.2) of
Section 2.2: For each occurrence πof the wildcard symbol inthebodyofprocedureproc,all
conditions leading to this occurrence are collected in a set Cπ. The exception guard exceptproc
then is defined as a boolean term representing the formula Wπ∈ΠVc∈Cπc,whereΠis the set
of all occurrences of inthebodyofprocedureproc.
One may think of the exception guard as a requirement such that exceptproc [x1/q1,...,x
n/qn]
is satisfied for q1,...,q
n∈C(P)iffthe computation of the procedure call proc(q1,...,q
n)raises
an exception, see [WS05b] for further details.1
1We wr i t e t[x1/t1,...,x
n/tn] for the term obtained from term tby replacing each variable symbol xiof t
by the term ti.
16
Example 7.
1. For all procedures of Example 3, the exception guards are given as false.
2. For procedure “−”from Example 5, except−is given as if {?0(y), false, ?0(x)}.
3. For the procedures “/”and “mod”from Example 5, except/and exceptmod both are given
as ?0(y).
4. For the procedure
function log2(x : N): N<=
if ?0(x)
then
else if ?0(−(x))
then 0
else if ?0(x mod 2) then +(log2(x /2))) else end
end
end
(computing the binary logarithm of powers of 2), the exception guard exceptlog2is given
as if {?0(x), true, if {?0(−(x)), false, ¬?0(x mod 2)}}.¥
3.1.2. The Computation Calculus
The interpreter evalPis defined by the so-called computation calculus which stipulates how
evalP(t) is computed for an expression t∈G(P). This calculus consists of so-called computation
rules of form t
r,ifcond(t, r)
where t, r ∈G(P)andcond(t, r) is a side condition controlling the application of the computation
rule.
We write t1⇒Pt2and call the replacement of t1by t2acomputation step , if some com-
putation rule applies for t1and t2, i.e. cond(t1,t
2)issatisfied for the pair of terms t1,t2.As
usual, ⇒+
Pdenotes the transitive closure of ⇒Pand ⇒∗
Pis the reflexive closure of ⇒+
P.We
write t⇒!
Pt0ifft⇒∗
Pt0for some t0∈G(P)andt0;Pt00 for each t00 ∈G(P). t⇓Pis defined as
t0iffexactly one t0such that t⇒!
Pt0exists.
Subsequently, we treat ¬bas an abbreviation for if (b, false,true ),andweassumethatdata
structure and procedure definitions are given in the same format as in (2.1) and (2.2) respectively.
Rules for Constructors, Selectors and Equality
?consi(con s i(q1,...,q
ni))
true ,ifq1,...,q
ni∈C(P) (3.1)
?consj(con s i(q1,...,q
ni))
false ,ifq1,...,q
ni∈C(P)andj6=i(3.2)
17
seli,h (con s i(q1,...,q
ni))
qh
,ifq1,...,q
ni∈C(P) (3.3)
q1=q2
true ,ifq1,q
2∈C(P)andq1=q2(3.4)
q1=q2
false ,ifq1,q
2∈C(P)andq16=q2(3.5)
Rules for Conditionals
if {b, t1,t
2}
if {b0,t
1,t
2},ifb⇒Pb0(3.6)
if {true,t
1,t
2}
t1
(3.7)
if {false,t
1,t
2}
t2
(3.8)
case {c;co ns 1:t1,...,co ns k:tk}
cas e {c0;cons 1:t1,...,co ns k:tk},ifc⇒Pc0(3.9)
cas e {cons i(q1,...,q
ni); con s 1:t1,...,con s k:tk}
ti
,ifq1,...,q
ni∈C(P) (3.10)
cas e {c;cons π(1) :tπ(1) ,...,co ns π(h):tπ(h),other :t}
case {c0;co ns π(1) :tπ(1),...,con s π(h):tπ(h),other :t},
if c⇒Pc0,whereπ:{1,...,k}→{1,...,k}is a bijective mapping
(3.11)
case {co ns i(q1,...,q
ni); con s π(1) :tπ(1),...,con s π(h):tπ(h),other :t}
ti
,
if q1,...,q
ni∈C(P)andi=π(j)forsomej≤h,
where π:{1,...,k}→{1,...,k}is a bijective mapping
(3.12)
18
case {co ns i(q1,...,q
ni); con s π(1) :tπ(1),...,con s π(h):tπ(h),other :t}
t,
if q1,...,q
ni∈C(P)andi6=π(j)foreachj≤h,
where π:{1,...,k}→{1,...,k}is a bijective mapping
(3.13)
Rules for let-Expressions
let{var:= t;r}
let{var := t0;r},ift⇒Pt0(3.14)
let{var:= t;r}
r[var/t],ift=t⇓P(3.15)
Rules for Function Applications
f(t1,...,t
i,...,t
n)
f(t1,...,t
0
i,...,t
n),iff/∈{if ,cas e ,let}and ti⇒Pt0
i(3.16)
proc(q1,...,q
k)
body proc [x1/q1,...,x
k/qk],if q1,...,q
k∈C(P)and
exceptproc [x1/q1,...,x
k/qk]⇓P=false (3.17)
3.1.3. The Interpreter evalP
The computation relation ⇒Pneither is noetherian (as Pmay contain non-terminating proce-
dures, cf. Section 3.1.4) nor deterministic (by presence of computation rule (3.16)). However,
⇒Pis confluent, i.e. for all t, t1,t
2∈G(P) such that t1∗
P⇐t⇒∗
Pt2some r∈G(P) satisfying
t1⇒∗
Pr∗
P⇐t2exists.
Each constructor ground term is ⇒P-minimal,i.e.q⇒!
Pqfor each q∈C(P), as no compu-
tation rule can be applied to a term q∈C(P). Each term t∈G(P)\C(P) satisfying t⇒!
Ptis
called a stuck computation. Those terms stem from
•the application of a selector to a constructor it does not belong to, as e.g. −(0), CAR(NIL),
DATA(CONS (...)), CDR(ATOM (...)) for the data structures of Example 1,
•the call of a procedure with arguments for which the exception guard is computed to a
term 6=false,e.g. 1/0, 1 mod (1/−(0)), log2(3) for the procedures of Examples 5 and 7,
•the computation of a conditional having a stuck computation as first argument, e.g.
if (?0(log2(3)),...,...), case (CAR(NIL); ...), and
•the application of a function symbol different from if and case to one stuck argument
at least, e.g. CDR(CAR(NIL)), CONS (NIL,CDR(NIL)), (1/0) mod 2, log2(3)/1=5,
+(−(0)).
19
By the confluence of ⇒P,foreacht∈G(P)atmostoner∈G(P) satisfying t⇒!
Prexists,
hence r=t⇓Pin such a case. Consequently, evalPis well-defined by stipulating
evalP(t):=⎧
⎨
⎩
t⇓P,ift⇒!
Prfor some r∈G(P)
⊥,otherwise.
3.1.4. Termination of L-Programs
Completely Defined Programs without Polymorphic Types
By presence of the wildcard symbol and the stuck computations caused by selectors applied
to constructors they do not belong to, L-programs are inherently incompletely defined.We
therefore call an L-program completely defined [WS05b] iff
•the wildcard symbol is not used in any procedure body, and
•witness terms ωseli,h containing only a variable xof type struct –given as in (2.1)–at
most are provided for each selector seli,h for defining the result of a selector applied to a
constructor it does not belong to.2
Aprocedure
function proc(x1:type1,...,x
k:typek):type <=body proc
of a completely defined L-program Pwithout polymorphic types terminates iff
evalP(proc(q1,...,q
k)) ∈C(P)type
•for each q1∈C(P)type1,...,q
k∈C(P)typek.3
A completely defined L-program Pwithout polymorphic types terminates iff
1. each procedure proc of Pterminates, and
2. evalP(ωsel i,h [x/q]) ∈C(P)typei,h for each q∈C(P)type.
Incompletely Defined Programs without Polymorphic Types
For defining termination of incompletely defined L-programs Pwithout polymorphic types, the
notion of a fair completion of program Pis used: A completely defined program P0is a fair
completion of program Piffthebodyofeachprocedure
function proc(x1:type1,...,x
k:typek):type <=body proc
in Pcoincides with the body of some procedure
function proc(x1:type1,...,x
k:typek):type <=body 0
proc
2There is no feature in Lallowing to assign witness terms. We abstain from extending Lby such a feature
as their is no practical use for those programs.
3evalP(t)∈C(P)isequivalenttoevalP(t)6=⊥as evalP(t)∈G(P)\C(P) is impossible by the requirements
for completely defined programs with monomorphic types.
20
in P0except for the unspecified -cases in body proc. Almost any result may be stipulated for those
cases in body 0
proc , however the fairness requirement demand that (i) termination of procedure
proc in P0not be spoiled just because procedure proc was completed by a non-terminating
result in a -case or (ii) a non-terminating witness term was assigned to a selector seli,h used in
body 0
proc .
Aprocedure
function proc(x1:type1,...,x
k:typek):type <=body proc
of an incompletely defined L-program Pwithout polymorphic types terminates iff
evalP0(proc(q1,...,q
k)) ∈C(P)type
•for each fair completion P0of P,and
•for each q1∈C(P)type1,...,q
k∈C(P)typek.
An incompletely defined L-program Pwithout polymorphic types terminates iffeach procedure
proc of Pterminates, see [WS05b] for further details.
Incompletely Defined Programs with Polymorphic Types
For defining termination of general L-programs P, we consider additional data structure defini-
tions in a fair completion P0of program Ptoo.
Aprocedure
function proc(x1:type1,...,x
k:typek):type <=body proc
of an L-program Pterminates iff
evalP0(proc(q1,...,q
k)) ∈C(P)θ(type)
•for each fair completion P0of P,
•for each type substitution θwhich replaces the type variables in type1,...,typek,type by
monomorphic types of P0yielding the monomorphic types θ(type1),...,θ(typek),
θ(type), and
•for each q1∈C(P)θ(type1),...,q
k∈C(P)θ(typek).foreachqi∈C(P)typei.
An L-program Pterminates iffeach procedure proc of Pterminates.
It should be noted that the existence of a diverging computation of a procedure call proc(q1,...,
qk)withargumentsqi∈C(P) entails non-termination of procedure proc. However, the converse
does not hold as there are non-terminating procedures causing no divergent computations.
21
Example 8.
1. Procedure
function null(x : N): N<=if ?0(x) then else null(null(−(x))) end
does not terminate as a non-terminating fair completion of this procedure exists, viz.
function null(x : N): N<=if ?0(x) then 1else null(null(−(x))) end .
However, each call of null with arguments from Ncauses a failed computation only, i.e.
no such procedure call results in a diverging computation although procedure null does
not terminate.
2. Each call of procedure
function loop(x : N):N<=loop(+(x)) end
with arguments from Ncauses a diverging computation, hence procedure loop does not
terminate.
3. All procedures of Examples 3, 4, 5 and 7 terminate. ¥
3.2. Semantics of Lemmas
A lemma
lemma lem <=∀x1:type1, ... , x
k:typekbody lem
of a terminating L-program Pis defined to be true iff
evalP0(bod y lem [x1/q1,...,x
k/qk]) = true
•for each fair completion P0of P,
•for each type substitution θwhich replaces the type variables in type1,...,typekby monomor-
phic types of P0yielding the monomorphic types θ(type1),...,θ(typek), and
•for each q1∈C(P)θ(type1),...,q
k∈C(P)θ(typek).
3.3. Domain Procedures
Partial definitions are a means to model undefinedness, cf. the procedures of Example 5 and pro-
cedure log2of Example 7. However, formally a procedure call like log2(0) denotes an unknown
value causing a failed computation only, whereas a procedure call like loop(0), cf. Example 8,
causes a diverging computation and does not denote a value at all.
22
By the semantics of L-lemmas, cf. Section 3.2, a lemma like
lemma lem1 <=∀x:Nx/0=xmod 0
is false, because a fair completion P0containing the fairly completed procedures “/”and“mod”
exists such that e.g. evalP0(0/0) = 0 but evalP0(0 mod 0) = 1. However, a lemma like
lemma lem2 <=∀x:Nx/0=x/0
is true, because evalP0(q/0=q/0) = true for each q∈C(P)Nand for any fair completion P0
containing the fairly completed procedure “/”, although evalPcomputes a stuck computation
as evalP(q/0=q/0) = q/0=q/0.
In order to recognize such unwanted truths caused by the differences between the
•semantics of data structures and procedures of an L-program Pgiven by the interpreter
evalPand the
•semantics of lemmas given by the interpreters evalP0of all fairly completed programs P0,
so-called domain procedures [WS05b] may be used: For any function symbol
f:type1×...×typek→type
of an L-program with f/∈{if ,cas e }, it is demanded that this L-program contains a domain
procedure
function ∇f(x1:type1,...,x
k:typek):bool <=bod y ∇f
satisfying for each type substitution θwhich replaces the type variables in type1,...,typekby
monomorphic types of P–yielding the monomorphic types θ(type1),...,θ(typek)–and for each
q1∈C(P)θ(type1),...,q
k∈C(P)θ(typek)
1. evalP(∇f(q1,...,q
k)) ∈G(P)⇔evalP(f(q1,...,q
k)) ∈G(P),
2. evalP(∇f(q1,...,q
k)) ∈C(P)⇔evalP(∇f(q1,...,q
k)) ∈G(P), and
3. evalP(∇f(q1,...,q
k)) = true ⇔evalP(f(q1,...,q
k)) ∈C(P).4
By requirement (1), the computation of ∇f(q1,...,q
k)diverges iffthe computation of
f(q1,...,q
k) diverges. By requirement (2), stuck computations are never obtained by call-
ing domain procedures. Finally by requirement (3), a domain procedure ∇fdecides for each
list q1,...,q
kof actual parameters whether a non-diverging computation of f(q1,...,q
k)fails
or succeeds. Section 4 provides examples for the use of domain procedures.
Example 9.
1. The domain procedure for procedure “+” from Example 3 is given as
function ∇+(x, y : N): bool <=true .
4In XeriFun, domain procedures (with fixity prefix) are automatically synthesized for each function symbol
different from a conditional.
23
2. The domain procedure for procedure mod from Example 5 is given as
function ∇mod(x, y : N): bool <=¬?0(y) .
3. The domain procedure for procedure log2from Example 7 is given as
function ∇log2(x : N): boo l <=
if ?0(x)
then false
else if ?0(−(x))
then true
else if ?0(x mod 2) then ∇log2(x /2) else false end
end
end .5¥
5Note that evalP(exceptproc [x1/q1,...,x
k/qk]) = true entails evalP(∇proc(q1,...,q
k)) = false but
evalP(∇proc(q1,...,q
k)) = false does not entail evalP(exceptproc [x1/q1,...,x
k/qk]) = true. For example,
evalP(∇log2(6)) = false,butevalP(exceptlog2[x/6]) = false as well.
24
4. The Tautology Checker - A Case Study
We illustrate the use of Lby a small case study taken from [BM79]. In this example, syntax
and semantics of a propositional language are defined, a tautology checker for formulas of this
language is given and lemmas stating soundness and completen ess of this procedure are provided.
We also give some of the auxiliary lemmas which are required to prove both main statements in
XeriFun .
4.1. Preliminaries
The propositional language is defined by the data structure
structure IF.Expr <=
T,
F,
PROP(index : N),
IF(test : IF.Expr, left : IF.Expr, right : IF.Expr)
where the constructor constants Tand Fare intended to denote truth and falsity,propositional
variables are given as PROP(0),PROP(1),PROP(2),... and IF is the only connectiv e of the
language intended to denote (a→b)∧(¬a→c)byatermIF(a, b, c).
As usual, the meaning of a propositional formula is given by a valuation, i.e. a mapping
which assigns truth values to propositional variables. As each propositional formula consists
of finitely many propositional variables only, a mapping assigning truth values to finitely many
propositional variables suffices. The graph of such a partial valuation can be represented by a
finite list of pairs (i, tv), where idenotes the index of the propositional variable PROP( i)to
which the truth value tv is assigned.
Truth values, pairs and lists are defined by the data structures
structure TruthValue <=TRUE,FALSE
structure pair[@ITEM1,@ITEM2] <=
[infixr,100] •([postfix] 1:@ITEM1,[postfix] 2:@ITEM2)
structure list[@ITEM] <=ø,[infixr,100] ::(hd : @ITEM, tl : list[@ITEM])
so that partial valuations can be represented by terms of type list [pair [N,TruthValue]]. This
type is an instance of the type list [pair [@ITEM1 ,@ITEM2 ]] the terms of which represent so-
called association lists. For those lists, the data associated with a certain key can be computed
by the procedure
25
function [infixl, 20] c
°(alist : list[pair[@ITEM1, @ITEM2]], key : @ITEM1) : @ITEM2 <=
if ?ø(alist)
then
else let head := hd(alist) in
if key = (head)1then (head)2else tl(alist) c
°key end if
end let
end if .
Since no data can be retrieved by procedure c
°if a key cannot be found in the association list,
the result of c
°is indetermined in such a case.1Consequently, the domain procedure of c
°is
given as
function ∇c
°(alist : list[pair[@ITEM1, @ITEM2]], key : @ITEM1) : bool <=
if ?ø(alist)
then false
else if key = (hd(alist))1then true else ∇c
°(tl(alist), key) end if
end if .
Using these definitions, the semantics of propositional formulas is defined by a procedure
function [infixr,10] ²(σ: list[pair[ N, TruthValue]], x : IF.Expr) : bool <=
case x o f
T : true ,
F:false,
PROP : ?TRUE( σc
°index(x)) ,
IF : if σ²test(x) then σ²left(x) else σ²right(x) end if
end case .
Procedure ²implements the satisfaction relation yielding true if a partial valuation σsatisfies
a propositional formula x, and yielding false if σfalsifies x. However, since it is not guaranteed
that each propositional variable of formula xconsidered by procedure ²is mentioned in the
partial valuation σ, computation of σ²xmight fail with a stuck computation.
4.2. The Tautology Checking Procedure
The base idea of the tautology checking algorithm is to decide for a propositional formula x
whether a given partial valuation σcan be extended to a valuation which falsifies x.Ifso,the
extended valuation is returned, and otherwise the algorithm reports failure about computing a
falsifying extension of σ. Now to check whether xis a tautology, the algorithm is called with
the empty valuation ø. If failure is reported, no falsifying valuation for xexists–hence each
valuation must satisfy x–and so xis a tautology. Otherwise there is some valuation falsifying
x,andthenxcannot be a tautology.
Theresulttypeofthetautologycheckerisgivenbythetypeofvaluationsexpandedbysome
failure indication. We therefore introduce the data structure
structure yields[@ITEM] <=⊥,return(result : @ITEM))
1By abuse of notation, “ c
°” stands for “content”.
26
to be used for defining the result type of the tautology checker.2This algorithm now can
implemented by the procedure
function 0(σ:list[pair[N, TruthValue]], x : IF.Expr) : yields[list[pair[N,TruthValue]]] <=
case x of
T:⊥,
F : return( σ),
PROP : let prop := index(x) in
if ∇c
°(σ, prop)
then if ?FALSE( σc
°prop) then return( σ)else ⊥end if
else return((prop •FA LS E ) :: σ)
end if
end let ,
IF : case test(x) of
T:σ0left(x) ,
F:σ0right(x) ,
PROP : let prop := index(test(x)) in
if ∇c
°(σ,prop)
then if ?TRUE( σc
°prop) then σ0left(x) else σ0right(x) end if
else let ρ:= (prop •TRUE) :: σ0left(x) in
if ? ⊥(ρ)then (prop •FA L SE ) :: σ0right(x) else ρend if
end let
end if
end let ,
IF :
end case
end case .
Procedure 0recursively explores a propositional formula x:Ifx=T,failure⊥is reported
as Tcannot be falsified, and the input valuation σis returned for x=F,asσ(vacuously)
falsifies F.Ifxis a propositional variable, domain procedure ∇c
°is used to decide whether xis
assigned a truth value by the partial valuation σ:Ifxis assigned FAL SE , the input valuation σ
is returned as σfalsifies x.Ifxis assigned TRUE , failure ⊥is reported as xcannot be falsified
by any extension of σ.If,however,xis not assigned a truth value, xcan be falsified by assigning
FAL S E to it, and this extension of σis returned as result.
If xis built with the IF -constructor, the result of 0is computed depending on the propo-
sitional formula test(x)inthetestofx:Iftest(x)isTor F, the respective alternatives have
to be explored recursively by 0.Iftest (x) is a propositional variable, domain procedure ∇c
°
is used again to decide whether test(x) is assigned a truth value by σ. Ifso,therespective
alternatives recursively have to be explored by 0. Otherwise the partial valuation σhas to be
extended: First it is tried to falsify the left branch of the IF -conditional under the additional
assumption that test(x)isTRUE . If this computation succeeds, the computed extension of σ
is returned. Otherwise it is tried to falsify the right branch of the IF -conditional under the
additional assumption that test(x)isFAL S E , and the result of this computation defines the
final result of 0.
2Data structure yields is generally useful to define the result type of procedures which–like the tautology
checker–decide whether some problem is solvable and return some solution if possible. Further examples for
those kinds of procedures are a unification algorithm or a parser.
27
The result of 0when applied to a propositional formula of form IF (IF (...),...)isleft
unspecified by procedure 0. This means that computations succeed only if 0is called with
propositional formulas free of IF ’s in the tests. We say that such formulas are in IF-normal
form, and one may verify that each propositional formula can be transformed into an equivalent
formula in IF -normal form.
The IF -normal form of a propositional formula is computed by procedure
function [outfix] k(x : IF.Expr) : IF.Expr <=
if ?IF(x)
then if ?IF(test(x))
then kIF(test(test(x)),
IF(left(test(x)), left(x), right(x)),
IF(right(test(x)), left(x), right(x))) k
else IF(test(x), kleft(x) k,kright(x) k)
end if
else x
end if
and
lemma normalization is sound <=∀σ: list[pair[ N, TruthValue]], x : IF.Expr
if {σ²kxk,σ²x, ¬σ²x}
states that normalization of a propositional formula xby procedure kcomputes a formula
equivalent to xin fact. The fact that computations of 0always succeed for formulas in IF -
normal form is expressed by
lemma normalization y0 determination <=
∀σ: list[pair[ N, TruthValue]], x : IF.Expr ∇0(σ, kxk).
3
4.3. Soundness of the Tautology Checking Procedure
Soundness of the tautology checker is stated by
lemma 0is sound <=∀σ: list[pair[ N, TruthValue]], x : IF.Expr
if {?⊥(ø 0kxk), σ²x , true}
asserting that eac h partial valuation σsatisfies a propositional formula xwhenever the tautology
checker–called with the normal form of xand the empty valuation ø–reports failure ⊥.To
prove this theorem, two auxiliary lemmas are needed:
lemma ²ignores assignments <=∀x:IF.Expr,σ: list[pair[ N, TruthValue]], n : N
if {(n •(σc
°n)) :: σ²x, σ²x, ¬σ²x},
states that duplicated assignments for propositional variables do not affect the satisfaction re-
lation, and
lemma 0soundness-lemma <=∀x:IF.Expr,σ,θ:list[pair[N, TruthValue]]
if {?⊥(θ0kxk), θ<>σ²x, true},
3Lemmas normalization is sound and normalization y0 determination are not required to verify soundness
and completeness of the tautology checker.
28
states that each partial valuation θ<>σsatisfies a propositional formula xwhenever the
tautology checker–called with the normal form of xand some partial valuation θ–reports
failure ⊥.4This lemma is the “key lemma” of the soundness proof, and lemma “0is sound ”
follows immediately from lemma “0soundness-lemma”simplybyreplacingθwith ø.
4.4. Completeness of the Tautology Checking Procedure
A tautology checker is complete iffan affirmative answer is returned when checking a propo-
sitional formula xwhich is satisfied by each valuation σof the propositional variables in x.
Consequently, the contraposition of this requirement demands that a falsifying valuation for a
formula xexists, if the tautology checker returns a negative answer for x.
When using procedure 0as the tautology checker, a negative answer is represented by a
result of form return(σ), where σis a falsifying valuation for x. Hence completeness of 0can
be stated by
∀x:IF .Expr ?return(ø0kxk)→∃σ:list[pa ir [N,TruthValue]] ¬σ²x. (4.1)
However, statement (4.1) cannot be written as an L-lemma, because it is not a universal formula
by presence of the existential quantifier in the conclusion of the implication. Hence a stronger
statement is formulated, viz.
∀x:IF .Expr ?return(ø0kxk)→¬res ult (ø0kxk)²x(4.2)
and, obviously, statement (4.2) entails statement (4.1). Since statement (4.2) is a universal
formula, completeness of the tautology checker now can be formulated by the L-lemma
lemma 0is complete <=∀x:IF.Expr
let{ρ:= ø 0kxk;if{?return( ρ), ¬result( ρ)²x, true}} .5
To prove this theorem, two further auxiliary lemmas are needed:
lemma 0extends valuations <=∀σ:list[pair[N, TruthValue]], x : IF.Expr, n : N
let{ρ:= σ0kxk;
if {?return( ρ), if {∇c
°(σ,n),σc
°n=result(ρ)c
°n, true}, true}} ,
states that 0computes an extension of the input valuation σindeed (provided 0returns a
valuation at all), and
lemma 0falsifies <=∀x:IF.Expr,σ: list[pair[ N, TruthValue]]
let{ρ:= σ0kxk;if{?return( ρ),¬result( ρ)²x, true}} ,
states that 0returns a valuation which falsifies the input formula x,provided0returns a
valuation at all. This lemma is the “key lemma” of the completeness proof, and lemma “0is
com ple te ” follows immediately from lemma “0falsifies”simplybyreplacingσwith ø.
4“<>” denotes list concatenation defined by procedure <> in Example 3.
5This example illustrates the general approach for the elimination of existential quantifiers in order to
formulate statements by L-lemmas: For a conjecture of form (1) ∀x:τx∃y:τyφ[x, y], a procedure fwith signature
f:τx→τyhas to be defined, such that (2) ∀x:τxφ[x, f (x)] holds. Then with a proof of (2), (1) is proved as
well.
29
5. Appendix
5.1. Character Set
L-expressions are formed of characters from a subset of unicode.1
5.2. Name Spaces
The following name spaces must be disjoint:
•the set of all type variables,
•the set of all type constructors,
•the set of all function symbols,
•the set of all formal parameters, local variables and variables of a lemma, and
•the set of all lemma names.
5.3. Naming Conventions
•type variables: any alphanumeric sequence of ascii characters preceded by “@” and not
containing blanks.
•type constructors, function symbols, formal parameters, local variables, variables of a
lemma: any sequence of unicode characters not preceded by “@”, “∇”or“∆” and not
containing blanks as well as any sequence of unicode characters beginning and ending
with “ 0”.
•lemma names: any sequence of unicode characters neither preceded by “@” nor con-
taining “<=” as well as any sequence of unicode characters beginning and ending with
“0”.
1XeriFun provides a table of all unicode characters available for writing L-expressions.
30
5.4. Reserved Words and Symbols
∀(Nall esac infixr postfix
:)bool false lemma pred
,{>case filet prefix
;}=else function nat structure
+[0end if not succ
−]¬end case in of then
<=:= end if infix other true
end let infixl outfix
as well as identifiers
•preceded by “∇” and not containing blanks,
•preceded by “∆p” and not containing blanks, where pis a superscripted number,
•ending with “p-bounded”, where pis a number,
•ending with “p-projection”, where pis a number, or
•containing one of the symbols with code 0x2592, 0x22D5, 0x2019.
5.5. Separation of Symbols
The following symbols have to be enclosed in blanks:
•function symbols of fixity infix,infixl and infixr as well as the predefined symbols “=”
(equality) and “>”(greater),
•the argument list of function symbols with fixity outfix,
•the negation operators “¬”and“not ”,
•“:”whenusedinatypedeclarationoracas e -expression.
5.6. Predefined and Implicitly Defined Procedures and Lemmas
•The data structures bool and N, cf. Example 1, and procedure “>”, cf. Example 3, are
predefined in L.
•Certain lemmas about +,−,=and >are predefined in L.2
•Domain procedures ∇fare implicitly defined for each function symbol fdifferent from if
and case , cf. Section 3.3.
•Difference procedures ∆pfare implicitly defined for some function symbols f, cf. [WS05a].
•Boundedness- and projection lemmas “fp-bounded”or“fp-projection” are implicitly
defined for some of the difference procedures ∆pf.
2These lemmas are collected in the folder Predefined which is part of each XeriFun session.
31
5.7. Aliases
The following aliases ease typing of L-expressions:3
Symbol Alias
Nnat
+(...)succ (...)
−(...)pred (...)
{...}(...)
end if end
end case end
end let end
∀all
¬not
x1:type,...,x
k:type x1,...,x
k:type
+(...
+
|{z }
ntimes
(0) ...)n,wheren≤42
3The use of parentheses instead of curly brackets may introduce syntactical ambiguities an L-parser cannot
resolve. Therefore curly brackets have to be used in those rare cases.
32
Index
actual parameter, 10
all,14
ascii,30
bool ,4,31
C(P), 16
C(P)τ,16
cas e ,6
cas e -expression, 6, 8
computation
calculus, 17
diverging, 16
failing, 16
rule, 17
step, 17
stuck, 16, 19
succeeding, 16
conditional
boolean, 6
structural, 6
connective, 14
constructor function, 6
constructor ground term, 16
data structure, 4
domain procedure, 23, 31
end,6,11
end cas e ,6
end if ,6
evalP, 16, 20
exceptproc,16
exception, 16
exception guard, 16
fair completion, 20, 21
fixity declaration, 7, 10
formal parameter, 10, 30
functional notation, 6, 11
G(P), 16
G(P)τ,16
ground term, 16
if ,6
if -expression, 6
in,11
infix,7,8,31
infixl,7,8,31
infixr,7,8,31
interpreter, 16
L-programm, 16
lemma, 13
let,11
let-expression, 11, 14
local variable, 11, 14, 30
nat,5
N,5,31
not,14
notation
functional, 6, 11
procedural, 6, 11
other ,6
outfix,7,31
parameter
actual, 10
formal, 10, 30
postfix,7
precedence, 7, 8
predefined, 4, 10
prefix,7
procedural notation, 6, 11
procedure, 9
incompletely defined, 12
selector function, 6
structure predicate, 6—8
stuck computation, 16, 19
33
term, 6
constructor ground, 16
ground, 16
termination
of procedures, 20
of programs, 20
type, 4, 5
constructor, 4, 30
monomorphic, 4, 5
polymorphic, 4, 5
variable, 4, 30
unicode,30
variable
local, 11, 14, 30
of a lemma, 13, 30
⇓P,17
⇒P,17
⇒!
P,17
⇒+
P,17
⇒∗
P,17
=,6,31
>, 10, 31
, 12, 16
34
Bibliography
[BHHW86] Susanne Biundo, Birgit Hummel, Dieter Hutter, and Christoph
Wa lt h e r . The Karlsruhe Induction Theorem Proving System. In J. H. Siek-
mann, editor, “Proc. of the 8th Inter. Conf. on Automated Deduction (CADE-8)”,
volume 230 of “Lecture Notes in Artificial Intelligence”, pages 672—674, Oxford, UK
(1986). Springer.
[BM79] Robert S. Boyer and J Strother Moore. “A Computational Logic”. Aca-
demic Press, NY (1979).
[CW85] Luca Cardelli and Peter Wegner. On Understanding Types, Data Abstrac-
tion, and Polymorphism. Computing Surveys 17(4), 471—522 (1985).
[Sch06] Stephan Schweitzer. Symbolische Auswertung und Heuristiken f¨ur Induktions-
beweise. Dissertation, Technische Universit¨at Darmstadt, to appear (2006).
[Ver] http://www.verifun.org.
[WS05a] Christoph Walther and Stephan Schweitzer. Automated Termination
Analysis for Incompletely Defined Programs. In Franz Baader and Andrei
Voronkov, editors, “Proc. of the 11th Inter. Conf. on Logic for Programming, Ar-
tificial Intelligence and Reasoning (LPAR-11)”, volume 3452 of “Lecture Notes in
Artificial Intelligence”, pages 332—346, Montevideo, Uruguay (2005). Springer.
[WS05b] Christoph Walther and Stephan Schweitzer. Reasoning about Incompletely
Defined Programs. In Geoff Sutcliffe and Andrei Voronkov,editors,“Proc.
of the 12th Inter. Conf. on Logic for Programming, Artificial Intelligence and Rea-
soning (LPAR-12)”, volume 3835 of “Lect. Notes in Artif. Intell.”, pages 427—442,
Montego Bay, Jamaica (2005). Springer.
35