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 deﬁnes 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 Deﬁnitions ................................... 4

2.1.2 TypesandTerms................................ 5

2.1.3 FixityDeclarations............................... 7

2.2 Procedures ....................................... 9

2.2.1 Deﬁnitions ................................... 9

2.2.2 Let-Expressions................................. 11

2.2.3 Incompletely DeﬁnedProcedures....................... 12

2.3 Lemmas ......................................... 13

2.3.1 Deﬁnitions ................................... 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 Predeﬁned and Implicitly DeﬁnedProceduresandLemmas ............ 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 veriﬁcation 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 deﬁne 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 veriﬁer. It was a rather obvious choice to incorporate features well known

from programming languages. But when we noticed that we were deﬁning our own functional

language, it was too late to switch over to a “real” programming language. Simply too much time

hadbeenspenttodeveloptheveriﬁer 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 veriﬁcation, it does not help to use a “real”

language containing features the veriﬁer does not support. This would rather mean to deﬁne

subsets of the “real” language by restricting it to language features the veriﬁer can cope with.

But it takes time to set up a veriﬁer 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 ﬂexible type

system, etc.?” This is simply because we ﬁrst 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 deﬁnition for it. So in the sequel, we deﬁne 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. Deﬁnitions

Adata structure is deﬁned 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) deﬁnes 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 (diﬀerent from the predeﬁned type bool –see Example 1) deﬁned

previously by other data structures,

•the symbols struct,co ns iand sel i,h are pairwise diﬀerent as well as diﬀerent from all

identiﬁers that have been previously introduced by data structure, procedure and lemma

deﬁnitions.

In addition,

•each type variable @Vjis used in one of the types typei,h diﬀerent 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 deﬁned by the L-expression

structure bool <=true,false .

This data structure is predeﬁned in L.

4

2. The monomorphic type Nis deﬁned by the L-expression

structure N<=0,+(−:N).

This data structure–deﬁning the natural numbers IN –is predeﬁned 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 deﬁned 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)deﬁnes binary trees which hold

their data in the leaves.

4. The polymorphic type LIST [@ITEM ]is deﬁned by the L-expression

structure LIST [@ITEM ]<=

EMPTY ,

ADD(HD :@ITEM ,TL :LIST [@ITEM ]) .

This data structure deﬁnes 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 deﬁned by the L-expression

structure tree [@ITEM ]<=

leaf (data :@ITEM ),

node(descendants :LIST [tree [@ITEM ]]) .

This data structure deﬁnes ﬁnitely branching trees the inner nodes of which may have

diﬀerent 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 deﬁnitions 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 deﬁnition DS as given in (2.1) deﬁnes 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 deﬁned 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 τ

diﬀerent from a type variable:

•=:τ×τ→bool ,whereτ6=bool ,

•if :bool ×τ×τ→τ,and

•cas e :τ0×τ×...×τ

|{z }

ktimes

→τ,whereτ0is some type deﬁned by a data structure with k

constructors.

The symbol =denotes equality and is written in inﬁxnotation.

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 τdeﬁned 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 deﬁnition of form (2.1) may be preceded by a ﬁxity

declaration of form

•[preﬁx],

•[postﬁx],

•[outﬁx],

•[inﬁx],

•[inﬁxl,N],or

•[inﬁxr,N ]

where N, called the precedence of the function symbol, is a numeral diﬀerent from 0.

preﬁxand post ﬁx

Fixity preﬁxis assumed by default if a ﬁxity declaration is missing and ﬁxity postﬁxplaces a

function symbol behind the list of arguments, i.e. (...)!for a postﬁxfunction symbol !as

compared to !(...)if!is declared preﬁxor no ﬁxity is declared for !at all.

Constant symbols cannot have a ﬁxity other than preﬁx. Also structure predicates ?cons

have always ﬁxity preﬁx, except if the constructor cons has ﬁxity outﬁx(see below).

outﬁx

If ﬁxity outﬁxis declared, 2 function symbols (not deﬁned elsewhere) separated by a colon

(enclosed in blanks) may (but need not) be used. For example, one may write

structure bintree [@ITEM ]<=

⊥,

[outﬁx]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

Aﬁxity declaration of form “[outﬁx]symbol” is treated like “[outﬁx]symbol :symbol”. So if

one replaces “[outﬁx]l:m”by“[outﬁx]|”intheabovedeﬁnition, terms of type bintree [N]are

written as

•|⊥,0,⊥|,

•||⊥,0,⊥|,1,⊥|,

4Note that the argument list of an outﬁxfunction symbol always has to be enclosed in blanks.

7

•||⊥,5,⊥|,1,|⊥,3,⊥||etc.

Theapplicationofastructurepredicate of a constructor “[outﬁx]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 .

inﬁx,inﬁxr and inﬁxl

These ﬁxity declarations are reserved for binary function symbols. One may deﬁne, for example,

structure SEXPR [@ITEM ]<=

NIL,

ATOM (DATA :@ITEM ),

[inﬁx]◦(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 [inﬁx]by[inﬁxl ,2]intheabovedeﬁnition,

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 diﬀerent 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,iftheinﬁxl function symbol ♦

has a greater precedence than the inﬁxl 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, inﬁxr 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 deﬁned by the L-expression

structure pair [@ITEM1,@ITEM2]<=

[inﬁx] •([postﬁx] 1: @ITEM1, [postﬁx] 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 deﬁned by the L-expression

structure list [@ITEM]<=

ø,[inﬁxr,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. Deﬁnitions

Aprocedure is deﬁned 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 identiﬁer diﬀerent from all identiﬁers that

have been previously introduced by data structure, procedure and lemma deﬁnitions,

•xiis a symbol diﬀerent from all type constructors and function symbols of the data struc-

ture and procedure deﬁnitions introduced so far,

•xi6=xj,ifi6=j,

•typeiis a type variable or a type built with type constructors diﬀerent from bool deﬁned

previously by some data structures,

•type is a type variable or a type built with type constructors deﬁnedpreviouslybysome

data structures, and

9

•each type variable in type also appears in some of the types typei.

A procedure deﬁnition 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 deﬁnitions 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 deﬁnition, the pro-

cedure function symbol may be preceded by a ﬁxity declaration in the head of the procedure

deﬁnition, 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 deﬁned by the procedure

function [inﬁxl,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 predeﬁned in L.5

2. Addition of natural numbers can be deﬁned by the procedure

function [inﬁxr,10] +(x, y : N): N<=

if ?0(x) then yelse +(−(x) + y) end .

3. Multiplication of natural numbers can be deﬁned by the procedure

function [inﬁxr,20] ∗(x, y : N): N<=

if ?0(x) then 0else −(x) ∗y+yend .

4. The factorial function can be deﬁned by the procedure

function [postﬁx] !(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 deﬁned by the procedure

function [inﬁxr,10] <>(k, l : list[@ITEM]) : list[@ITEM]<=

if ?ø(k) then lelse hd(k) :: (tl(k) <> l) end .

6. Thelengthofalistcanbecomputedbytheprocedure

function [outﬁx] |(k : list[@ITEM]): N<=

if ?ø(k) then 0else +(|tl(k) |)end .

7. Deletion of list elements can be deﬁned by the procedure

function [inﬁxr,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 deﬁned 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 identiﬁer–called a local variable–which is diﬀerent from the formal para-

meters of the procedure and from all type constructors and function symbols of the data

structure and procedure deﬁnitions 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 deﬁned 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 Deﬁned Procedures

For some procedures, a meaningful result cannot be deﬁned for certain inputs or it is impossible

to stipulate a result for certain inputs at all. For example, it is not meaningful to deﬁne 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 deﬁned

for the empty list.

As a remedy, the wildcard symbol may be used to denote an unspeciﬁed result in a pro-

cedure body by writing in the alternatives of a conditional, yielding a incompletely deﬁned

procedure. Incompletely deﬁned procedures (also known as loose speciﬁcations or underspeciﬁ-

cations in the literature) are in particular useful to avoid artiﬁcial 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 deﬁned by the procedure

function [inﬁxl,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 deﬁned by the procedure

function [inﬁxl,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 deﬁned by the procedure

function [inﬁxr,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 deﬁned 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. Deﬁnitions

Alemma is deﬁned 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 identiﬁer diﬀerent from all identiﬁers that have

been previously introduced by data structure, procedure and lemma deﬁnitions,

•xiis an identiﬁer–called a variable of the lemma–diﬀerent from all identiﬁers denoting

type constructors and function symbols of the data structure and procedure deﬁnitions

introduced so far,

•xi6=xj,ifi6=j,

•typeiis an identiﬁer denoting a type variable or a type built with type constructors diﬀerent

from bool deﬁned 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 deﬁnitions introduced so far.

Like in procedure deﬁnitions, 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 deﬁnition. Also let -expressions may

be used in the lemma body, cf. Section 2.2, where, however, the local variables must be diﬀerent

from the variables of the lemma. The universal quantiﬁer “∀” 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 deﬁne 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 deﬁnitions, 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 deﬁnitions 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 deﬁned 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 deﬁned procedures, cf. Section 2.2.3, a

so-called ex cept ion g uard ex cept proc is associated with each procedure proc as deﬁned 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 deﬁned 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 satisﬁed for q1,...,q

n∈C(P)iﬀthe 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 deﬁned 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)issatisﬁed for the pair of terms t1,t2.As

usual, ⇒+

Pdenotes the transitive closure of ⇒Pand ⇒∗

Pis the reﬂexive closure of ⇒+

P.We

write t⇒!

Pt0iﬀt⇒∗

Pt0for some t0∈G(P)andt0;Pt00 for each t00 ∈G(P). t⇓Pis deﬁned as

t0iﬀexactly one t0such that t⇒!

Pt0exists.

Subsequently, we treat ¬bas an abbreviation for if (b, false,true ),andweassumethatdata

structure and procedure deﬁnitions 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 conﬂuent, 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 ﬁrst argument, e.g.

if (?0(log2(3)),...,...), case (CAR(NIL); ...), and

•the application of a function symbol diﬀerent 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 conﬂuence of ⇒P,foreacht∈G(P)atmostoner∈G(P) satisfying t⇒!

Prexists,

hence r=t⇓Pin such a case. Consequently, evalPis well-deﬁned by stipulating

evalP(t):=⎧

⎨

⎩

t⇓P,ift⇒!

Prfor some r∈G(P)

⊥,otherwise.

3.1.4. Termination of L-Programs

Completely Deﬁned 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 deﬁned.We

therefore call an L-program completely deﬁned [WS05b] iﬀ

•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 deﬁning 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 deﬁned L-program Pwithout polymorphic types terminates iﬀ

evalP(proc(q1,...,q

k)) ∈C(P)type

•for each q1∈C(P)type1,...,q

k∈C(P)typek.3

A completely deﬁned L-program Pwithout polymorphic types terminates iﬀ

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 Deﬁned Programs without Polymorphic Types

For deﬁning termination of incompletely deﬁned L-programs Pwithout polymorphic types, the

notion of a fair completion of program Pis used: A completely deﬁned program P0is a fair

completion of program Piﬀthebodyofeachprocedure

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 deﬁned programs with monomorphic types.

20

in P0except for the unspeciﬁed -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 deﬁned L-program Pwithout polymorphic types terminates iﬀ

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 deﬁned L-program Pwithout polymorphic types terminates iﬀeach procedure

proc of Pterminates, see [WS05b] for further details.

Incompletely Deﬁned Programs with Polymorphic Types

For deﬁning termination of general L-programs P, we consider additional data structure deﬁni-

tions in a fair completion P0of program Ptoo.

Aprocedure

function proc(x1:type1,...,x

k:typek):type <=body proc

of an L-program Pterminates iﬀ

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 iﬀeach 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 deﬁned to be true iﬀ

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 deﬁnitions are a means to model undeﬁnedness, 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 diﬀerences 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 iﬀthe 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 ﬁxity preﬁx) are automatically synthesized for each function symbol

diﬀerent 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 deﬁned, 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 deﬁned 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 ﬁnitely many propositional variables only, a mapping assigning truth values to ﬁnitely many

propositional variables suﬃces. The graph of such a partial valuation can be represented by a

ﬁnite 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 deﬁned by the data structures

structure TruthValue <=TRUE,FALSE

structure pair[@ITEM1,@ITEM2] <=

[inﬁxr,100] •([postﬁx] 1:@ITEM1,[postﬁx] 2:@ITEM2)

structure list[@ITEM] <=ø,[inﬁxr,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 [inﬁxl, 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 deﬁnitions, the semantics of propositional formulas is deﬁned by a procedure

function [inﬁxr,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 σsatisﬁes

a propositional formula x, and yielding false if σfalsiﬁes 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 falsiﬁes 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 deﬁning 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 falsiﬁed, and the input valuation σis returned for x=F,asσ(vacuously)

falsiﬁes 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 σfalsiﬁes x.Ifxis assigned TRUE , failure ⊥is reported as xcannot be falsiﬁed

by any extension of σ.If,however,xis not assigned a truth value, xcan be falsiﬁed 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 deﬁnes the

ﬁnal result of 0.

2Data structure yields is generally useful to deﬁne 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 uniﬁcation algorithm or a parser.

27

The result of 0when applied to a propositional formula of form IF (IF (...),...)isleft

unspeciﬁed 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 [outﬁx] 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 σsatisﬁes 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 aﬀect 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 θ<>σsatisﬁes 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 iﬀan aﬃrmative answer is returned when checking a propo-

sitional formula xwhich is satisﬁed 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 quantiﬁer 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 0falsiﬁes <=∀x:IF.Expr,σ: list[pair[ N, TruthValue]]

let{ρ:= σ0kxk;if{?return( ρ),¬result( ρ)²x, true}} ,

states that 0returns a valuation which falsiﬁes 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 “0falsiﬁes”simplybyreplacingσwith ø.

4“<>” denotes list concatenation deﬁned by procedure <> in Example 3.

5This example illustrates the general approach for the elimination of existential quantiﬁers 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 deﬁned, 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 inﬁxr postﬁx

:)bool false lemma pred

,{>case ﬁlet preﬁx

;}=else function nat structure

+[0end if not succ

−]¬end case in of then

<=:= end if inﬁx other true

end let inﬁxl outﬁx

as well as identiﬁers

•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 ﬁxity inﬁx,inﬁxl and inﬁxr as well as the predeﬁned symbols “=”

(equality) and “>”(greater),

•the argument list of function symbols with ﬁxity outﬁx,

•the negation operators “¬”and“not ”,

•“:”whenusedinatypedeclarationoracas e -expression.

5.6. Predeﬁned and Implicitly Deﬁned Procedures and Lemmas

•The data structures bool and N, cf. Example 1, and procedure “>”, cf. Example 3, are

predeﬁned in L.

•Certain lemmas about +,−,=and >are predeﬁned in L.2

•Domain procedures ∇fare implicitly deﬁned for each function symbol fdiﬀerent from if

and case , cf. Section 3.3.

•Diﬀerence procedures ∆pfare implicitly deﬁned for some function symbols f, cf. [WS05a].

•Boundedness- and projection lemmas “fp-bounded”or“fp-projection” are implicitly

deﬁned for some of the diﬀerence 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

ﬁxity 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

inﬁx,7,8,31

inﬁxl,7,8,31

inﬁxr,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

outﬁx,7,31

parameter

actual, 10

formal, 10, 30

postﬁx,7

precedence, 7, 8

predeﬁned, 4, 10

preﬁx,7

procedural notation, 6, 11

procedure, 9

incompletely deﬁned, 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 Artiﬁcial 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 Deﬁned Programs. In Franz Baader and Andrei

Voronkov, editors, “Proc. of the 11th Inter. Conf. on Logic for Programming, Ar-

tiﬁcial Intelligence and Reasoning (LPAR-11)”, volume 3452 of “Lecture Notes in

Artiﬁcial Intelligence”, pages 332—346, Montevideo, Uruguay (2005). Springer.

[WS05b] Christoph Walther and Stephan Schweitzer. Reasoning about Incompletely

Deﬁned Programs. In Geoff Sutcliffe and Andrei Voronkov,editors,“Proc.

of the 12th Inter. Conf. on Logic for Programming, Artiﬁcial Intelligence and Rea-

soning (LPAR-12)”, volume 3835 of “Lect. Notes in Artif. Intell.”, pages 427—442,

Montego Bay, Jamaica (2005). Springer.

35