I want to explain how to read the HOL Light basics from the source code in 
several sections
0) colloquial (informal) math and HOL
1) the definitions of type bool and the constant = 
2) sequents, new_basic_definition and the HOL Light inference rules
3) The BETA_CONV proof of general beta-conversion
4) the bool.ml definitions of !, <=>, T, F, /\, ==>, ~, \/ 
5) the properties of the type bool.

Section 2 corrects an error I posted about = and T_DEF.  Sections 0--4 are 
finished.  In section  5, which I hope is just reinventing Gordon and Melham's 
wheel, I got as far as explaining CONJ, which easily gives a "truth table" 
result 
|- T ∧ T ⇔ T

***** 0) colloquial (informal) mathematics and HOL *****

The 10 primitive HOL Light inference rules are expressed as Ocaml functions 
which take theorems to theorems, theorems being certain types of Ocaml objects 
called sequents.  One normally discusses these functions in the language of 
informal mathematics.  For instance, the reference manual describes the 
non-primitive inference rule as 

BETA_CONV : term -> thm
The conversion BETA_CONV maps a beta-redex `(\x.u)v` to the theorem
   |- (\x.u)v = u[v/x]

In informal mathematics, one would phrase this as:

Theorem:
For all variables x and for all terms u and v, we have the sequent
   |- (\x.u)v = u[v/x]

I contend that there is a lot of clarity to be gained by discussing HOL in this 
informal mathematics style, and I'll do so in section 5 below.  However, from 
the perspective of thinking of HOL as mathematical foundations, such informal 
mathematics makes no sense.  Note my use of `For all' in the `Theorem' above.  
In informal mathematics we think we know what `for all' and `theorem' mean, but 
in HOL, we're trying to carefully define their meanings!  Nonetheless, for 
parts of HOL that are hard to understand, an informal mathematical style may be 
quite helpful.  One might even say that the reference manual is written in this 
informal mathematical style.  And I find boolean matters such as the truth 
table for AND and the law of the excluded middle hard to understand.

***** 1) the definitions of type bool and the constant =  *****

 First, the type bool is defined in fusion.ml by the line which creates a fresh 
Ocaml (mutable) reference the_type_constants which is a list of pairs (as 
Ramana and Mark pointed out)

  let the_type_constants = ref ["bool",0; "fun",2]

which means that bool is a type and fun takes two types as arguments and 
returns a type.  My guess is that fun is bound to -> in parser.ml in the line 

  let rec pretype i = rightbin sumtype (a (Resword "->")) (btyop "fun") "type" i

The type ind (explained to an abbreviation for Church's type of individuals in 
a comment) is defined in nums.ml by 

new_type ("ind",0);;

The function new_type is defined in fusion.ml to essentially add a new pair to 
the reference the_type_constants. All new constants except = are created by the 
function new_constant, which essentially conses a new constant to the mutable 
reference list the_term_constants, which defines the first constant =: 

  let the_term_constants =
     ref ["=",Tyapp("fun",[aty;Tyapp("fun",[aty;bool_ty])])]

We see this means that = has type A->A->bool from the fusion.ml code

  let constants() = !the_term_constants
  let bool_ty = Tyapp("bool",[])
  let aty = Tyvar "A"
  let mk_type(tyop,args) =
    [...]  Tyapp(tyop,args) [...]
  let mk_vartype v = Tyvar(v)

and inspecting the Ocaml code below and the output:

# hd (rev (constants()));;
val it : string * hol_type = ("=", `:A->A->bool`)
# mk_vartype "A";;
val it : hol_type = `:A`
# mk_type("fun",[mk_vartype "A"; mk_type("fun",[mk_vartype "A"; 
mk_type("bool",[])])]);;
val it : hol_type = `:A->A->bool`

***** 2) sequents, new_basic_definition and the HOL Light inference rules *****
I'll explain how Tom Hales's description of HOL Light inference rules is found 
in this 545 line segment of the file fusion.ml
module Hol : Hol_kernel = struct
[...]
end;;
Similar code is found in the 150 line segment of the file thm.ml 
module Hol : Hol_thm_primitives = struct
[...]
end;;
but I won't discuss this.  My guess is that the fusion.ml definitions are used 
first for some basic theorem and then the thm.ml definitions are used for more 
sophisticated or faster handling of theorems.  

A theorem is an Ocaml object of type thm:

  type thm = Sequent of (term list * term)

So a theorem is of the form Sequent ([a1;...;an], t), which we will write as 

{a1,...,an} |- t

It will turn out that t will always have type bool.

Sequent is an Ocaml constructor defined in the module Hol.  Thus we have no way 
to produce theorems except by sequent-producing functions defined in Hol, 
including new_basic_definition, about which the reference manual says:

If t is a closed term and c a variable whose name has not been used as
a constant, then new_basic_definition `c = t` will define a new
constant c and return the theorem |- c = t for that new constant (not
the variable in the given term)

We can see the sequent being produced in the code

  let new_basic_definition tm =
    match tm with
      Comb(Comb(Const("=",_),Var(cname,ty)),r) -> [...] 
             let dth = Sequent([],safe_mk_eq c r) [...] 

Another way to produce sequents is with the Hol module function 
new_basic_type_definition.  

The only other way to produce sequents is with 10 Hol module functions which 
produce theorems from earlier theorems:
REFL, TRANS, MK_COMB, ABS, BETA, ASSUME, EQ_MP, DEDUCT_ANTISYM_RULE, INST_TYPE 
and INST.  Here are the reference manual description of the 10 function,
with two corrections given by Hales, so 
in TRANS, t2 and t2' are alpha-equivalent, and 
in EQ_MP, t1 and t1' are alpha-equivalent.
Each reference manual description ends with
COMMENTS
    This is one of HOL Light's 10 primitive inference rules. 

REFL : term -> thm
Returns theorem expressing reflexivity of equality.
REFL maps any term `t` to the corresponding theorem |- t = t. 

TRANS : thm -> thm -> thm
Uses transitivity of equality on two equational theorems.
        A1 |- t1 = t2   A2 |- t2' = t3
       -------------------------------  TRANS
             A1 u A2 |- t1 = t3

MK_COMB : thm * thm -> thm
Proves equality of combinations constructed from equal functions and operands. 
        A1 |- f = g   A2 |- x = y
       ---------------------------  MK_COMB
           A1 u A2 |- f x = g y

ABS : term -> thm -> thm
Abstracts both sides of an equation. 
A |- t1 = t2
   ------------------------  ABS `x`            [Where x is not free in A]
    A |- (\x.t1) = (\x.t2)

BETA : term -> thm
Special primitive case of beta-reduction.
|- (\x. t[x]) x = t[x].

ASSUME : term -> thm
Introduces an assumption. 
 --------  ASSUME `t`
    t |- t

EQ_MP : thm -> thm -> thm
Equality version of the Modus Ponens rule. 
A1 |- t1' <=> t2   A2 |- t1
   ----------------------------  EQ_MP
         A1 u A2 |- t2

DEDUCT_ANTISYM_RULE : thm -> thm -> thm
Deduces logical equivalence from deduction in both directions. 
      A |- p       B |- q
  ----------------------------------
   (A - {q}) u (B - {p}) |- p <=> q

INST_TYPE : (hol_type * hol_type) list -> thm -> thm
Instantiates types in a theorem.
               A |- t
   -----------------------------------  INST_TYPE [ty1,tv1;...;tyn,tvn]
    A[ty1,...,tyn/tv1,...,tvn]
        |- t[ty1,...,tyn/tv1,...,tvn]

INST : (term * term) list -> thm -> thm
Instantiates free variables in a theorem.
               A |- t
   -----------------------------------  INST_TYPE [t1,x1;...;tn,xn]
    A[t1,...,tn/x1,...,xn]
        |- t[t1,...,tn/x1,...,xn]
Bound variables will be renamed if necessary to avoid capture. All variables 
are substituted in parallel, so there is no problem if there is an overlap 
between the terms ti and xi.

We can see that Hales is correct about alpha-equivalence from the code, e.g. 

  let EQ_MP (Sequent(asl1,eq)) (Sequent(asl2,c)) =
    match eq with
      Comb(Comb(Const("=",_),l),r) when alphaorder l c = 0
        -> Sequent(term_union asl1 asl2,r)
    | _ -> failwith "EQ_MP"

alphaorder : term -> term -> int
returns 0 if and only if the two terms are alpha-convertible.

***** 3) the BETA_CONV proof of the general case of beta-conversion *****

The fusion.ml code for BETA clearly shows that 

BETA (\v. bod) v) = (|- ((\v. bod) v) = bod)

In informal math,  we say that for any abstraction (\v. bod), we have the 
theorem

|- ((\v. bod) v) = bod

Applying INST [arg,v] to this theorem we have 

|- ((\v. bod) arg) = bod[arg,v]

That's the general case of beta-conversion, for any abstraction (\v. bod) and 
any term arg.

More formally, by definition of BETA_CONV in equal.ml, 

BETA_CONV (\v. bod) arg = INST [arg,v] (|- ((\v. bod) v) = bod) = 

(|- (\v. bod) arg) = bod[arg,v])


***** 4) the bool.ml definitions of ! (forall), <=> (iff), T (true), F (false), 
/\ (and), ==> (implies), ~ (not), \/ (or) and ? (exists) *****

The binder !A->bool->bool is defined by 

let FORALL_DEF = new_basic_definition
 `(!) = \P:A->bool. P = \x. T`;;

We infer the type of ! from the fact that = has type A->A->bool.  I believe the 
definition of binder is that parser.ml will replace an expression
!x. body
for any term body:A->bool with
(!)(\x. body)

The infix <=> is defined to be = when both arguments have type bool by 

override_interface ("<=>",`(=):bool->bool->bool`);;

The term T is are defined to have type bool by 

let T_DEF = new_basic_definition
 `T = ((\p:bool. p) = (\p:bool. p))`;;

Note a subtlety about = here which I messed up in a previous post.  The first = 
is the Ocaml =, meaning that T_DEF is bound in Ocaml to the value of the 
new_basic_definition expression.  Each of the other two =s is the constants = 
of type A->A->bool.  Therefore the RHS (\p:bool. p) = (\p:bool. p) has type 
bool, and therefore T has type bool.

F is defined to have type bool by 

let F_DEF = new_basic_definition
 `F = !p:bool. p`;;

The infix /\:bool->bool->bool is defined by 

let AND_DEF = new_basic_definition
 `(/\) = \p q. (\f:bool->bool->bool. f p q) = (\f. f T T)`;;

because we infer the types of p and q from the type of f.  

The infix ==> :bool->bool->bool is defined by

let IMP_DEF = new_basic_definition
  `(==>) = \p q. p /\ q <=> p`;;

The prefix ~ is defined by 

let NOT_DEF = new_basic_definition
 `(~) = \p. p ==> F`;;

I think the parser treats prefixes in a special way, but I'm not sure what it 
is.

The infix \/:bool->bool->bool is defined by 

let OR_DEF = new_basic_definition
 `(\/) = \p q. !r. (p ==> r) ==> (q ==> r) ==> r`;;

The binder ?: A->bool->bool is defined by 

let EXISTS_DEF = new_basic_definition
 `(?) = \P:A->bool. !q. (!x. P x ==> q) ==> q`;;

so parser.ml will replace an expression
!x. body
for any term body:A->bool with
(?)(\x. body)

***** 5) An informal mathematical discussion of the type bool *****

The first thing we need is prove that |- ~(T <=> F), and to construct "truth 
tables" for the functions ~, /\, \/ and ==>.  A truth table for ~ means proving 
the two theorems 
|- ~F = T
|- ~T = F
This seems to be difficult, and is only accomplished in itab.ml, which defines 
the prover ITAUT and the tactic ITAUT_TAC, and this requires tactics.ml, 
drule.ml and bool.ml.
Then we need to prove  
BOOL_CASES_AX;;
val it : thm = |- !t. (t <=> T) \/ (t <=> F)
This is only accomplished in class.ml, which requires additionally ind_defs.ml, 
theorems.ml, simp.ml and the axioms select and extensionality axioms 
SELECT_AX and ETA_AX.

As these matters appear hard to me, I'll adopt an informal mathematical style, 
and I'll use the 10 theorems represented by the primitive inference function, 
and call them axiom REFL, axiom TRANS, axiom MK_COMB, axiom ABS, axiom BETA, 
axiom ASSUME, axiom EQ_MP, axiom DEDUCT_ANTISYM_RULE, axiom INST_TYPE and axiom 
INST.  Let's first record our informal mathematical theorem BETA_CONV above:

Theorem BETA_CONV:
For any variable v and terms bod and arg, we have the sequent
|- ((\v. bod) arg) = bod[arg,v] 

AP_TERM, AP_THM and SYM of equal.ml give simple proofs of 

Theorem AP_TERM:
For all terms f, x and y and for all sequents
A |- x = y
we have the sequent
A |- f x = f y.

Proof:
By axiom REFL, we have the sequent
|- f = f.
Now apply axiom MK_COMB to this sequent and our assumption, noting that 
A ∪ ∅ = A.
\qed

Theorem AP_THM:
For all terms f, g and x and for all sequents
A |- f = g
we have the sequent
A |- f x = g x.

Proof:
Apply axiom MK_COMB to our assumption and the axiom REFL sequent |- x = x.
\qed


Theorem SYM:
For all terms l and r and for all sequents
A |- l = r
we have the sequent
A |- r = l.

Proof:
For precision, let α be the type of l, which is also the type of r.  Applying 
=:α->α->bool to our assumption and using theorem AP_TERM, we have the sequent 
A |- (= l) = (= r)
By axiom REFL we have the sequent 
|- (l = l).
Applying axiom EQ_MP to these two sequents, we have the sequent 
A |- (= l) l = (= r) l
since A ∪ ∅ = A.  By the parser.ml definition of the infix =, we have the 
sequent 
A |- (l = l) = (r = l).
By our REFL sequent above, axiom EQ_MP and A ∪ ∅ = A, we're done.
\qed

Now we prove the first results of bool.ml.

Theorem TRUTH:
We have the sequent
|- T

Proof:
By T_DEF and new_basic_definition we have the sequent
|- T = ((λp:bool. p) = (λp:bool. p)).
By theorem SYM have the sequent
|- ((λp:bool. p) = (λp:bool. p)) = T.
By axiom REFL we have the sequent 
|- (λp:bool. p) = (λp:bool. p)
Applying axiom EQ_MP to these two sequents, we are done.
\qed


Our next result follows immediately from theorem SYM, theorem TRUTH and axiom 
EQ_MP.

Theorem EQT_ELIM:
For all terms tm and all sequents
A |- tm ⇔ T
we have the sequent
A |- tm.

The converse takes a little more work.

Theorem EQT_INTRO:
For all terms tm and all sequents
A |- tm
we have the sequent
A |- tm ⇔ T.

Proof:
By axiom ASSUME and theorem TRUTH we have the sequents
{tm} |- tm
|- T
so by axiom DEDUCT_ANTISYM_RULE we have the sequent
{tm} |- tm ⇔ T.
By axiom ASSUME applied to tm ⇔ T and theorem EQT_ELIM, we have the sequent
{tm ⇔ T} |- tm.
Applying axiom DEDUCT_ANTISYM_RULE to these "converse" sequents, we have the 
sequent
|- tm ⇔ (tm ⇔ T)
Applying axiom EQ_MP to this and our assumption, we are done.
\qed

Note this gives a proof 2 lines shorter than the version in bool.ml

let EQT_INTRO th =
  let th1 = DEDUCT_ANTISYM_RULE (ASSUME (concl th)) TRUTH in
  let th2 = EQT_ELIM(ASSUME(concl th1)) in
  let pth = DEDUCT_ANTISYM_RULE th2 th1 in
  EQ_MP pth th;;

which I checked actually works.

Theorem CONJ:
For any two terms p and q of type bool with seqents
A1 |- t1      
A2 |- t2,
we have the seqent
A1 ∪ A2 |- t1 ∧ t2

Proof:
Choose a variable fof type bool->bool->bool which is not free in t1 or t2.
By our assumptions and theorem EQT_INTRO, we have the sequents
A1 |- t1 ⇔ T
A2 |- t2 ⇔ T
Applying theorem AP_TERM with f to the first gives the sequent
A1 |- f t1 ⇔ f T
Applying axiom MK_COMB to this and the previous sequent yields
A1 ∪ A2 |- f t1 t2 ⇔ f T T
By axiom ABS, we have
A1 ∪ A2 |- (λf. f t1 t2) ⇔ (λf. f T T)
Apply theorem AP_TERM twice to the AND_DEF sequent
|- (∧) = λp q. (λf:bool->bool->bool. f p q) = (λf. f T T)
with the terms t1 and then t2 to obtain the sequent
|- (∧) t1 t2 = (λp q. (λf:bool->bool->bool. f p q) = (λf. f T T)) t1 t2
Applying theorem BETA_CONV twice and axiom TRANS twice, we have the sequent
|- t1 ∧ t2 = ((λf. f t1 t2) ⇔ (λf. f T T)).
By theorem SYM, axiom EQ_MP and our A1 ∪ A2 sequent above, we're done.
\qed

Theorems CONJ,  TRUTH and EQT_INTRO  gives us our first AND "truth table" 
result:

Theorem CONJ_EZ:
|- T ∧ T ⇔ T

-- 
Best,
Bill

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
hol-info mailing list
hol-info@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/hol-info

Reply via email to