new_recursive_definition : {name:string, def:term, rec_axiom:thm} -> thm
A theorem th of the form returned by define_type is a primitive recursion theorem for an automatically-defined concrete type ty. Let C1, ..., Cn be the constructors of this type, and let ‘(Ci vs)’ represent a (curried) application of the ith constructor to a sequence of variables. Then a curried primitive recursive function fn over ty can be specified by a conjunction of (optionally universally-quantified) clauses of the form:
fn v1 ... (C1 vs1) ... vm = body1 /\
fn v1 ... (C2 vs2) ... vm = body2 /\
.
.
fn v1 ... (Cn vsn) ... vm = bodyn
fn t1 ... v ... tm
If tm is a conjunction of clauses, as described above, then evaluating:
new_recursive_definition{name=name, rec_axiom=th,def=tm}
new_recursive_definition also allows the supplied definition to omit clauses for any number of constructors. If a defining equation for the ith constructor is omitted, then the value of fn at that constructor:
fn v1 ... (Ci vsi) ... vn
|- !f0 f1.
?! fn.
(!x. fn(LEAF x) = f0 x) /\
(!b1 b2. fn(NODE b1 b2) = f1(fn b1)(fn b2)b1 b2)
- val Leaves = new_recursive_definition
{name = "Leaves",
rec_axiom = th,
def= --`(Leaves (LEAF (x:'a)) = 1) /\
(Leaves (NODE t1 t2) = (Leaves t1) + (Leaves t2))`--};
> val Leaves =
|- (!x. Leaves (LEAF x) = 1) /\
!t1 t2. Leaves (NODE t1 t2) = Leaves t1 + Leaves t2 : thm
The function defined using new_recursive_definition need not, in fact, be recursive. Here is the definition of a predicate IsLeaf, which is true of binary trees which are leaves, but is false of the internal nodes in a binary tree:
- val IsLeaf = new_recursive_definition
{name = "IsLeaf",
rec_axiom = th,
def = --`(IsLeaf (NODE t1 t2) = F) /\
(IsLeaf (LEAF (x:'a)) = T)`--};
> val IsLeaf = |- (!t1 t2. IsLeaf (NODE t1 t2) = F) /\
!x. IsLeaf (LEAF x) = T : thm
new_recursive_definition also allows the user to partially specify the value of a function defined on a concrete type, by allowing defining equations for some of the constructors to be omitted. Here, for example, is the definition of a function Label which extracts the label from a leaf node. The value of Label applied to an internal node is left unspecified:
- val Label = new_recursive_definition
{name = "Label",
rec_axiom = th,
def = --`Label (LEAF (x:'a)) = x`--};
> val Label = |- !x. Label (LEAF x) = x : thm
- val _ = set_fixity ("<<", Infixl 231);
- val Subtree = new_recursive_definition
{name = "Subtree",
rec_axiom = th,
def = --`($<< (t:'a bintree) (LEAF (x:'a)) = F) /\
($<< t (NODE t1 t2) = (t = t1) \/
(t = t2) \/
($<< t t1) \/
($<< t t2))`--};
> val Subtree =
|- (!t x. t << LEAF x = F) /\
!t t1 t2.
t << NODE t1 t2 = (t = t1) \/ (t = t2) \/
(t << t1) \/ (t << t2) : thm