1 (* ========================================================================= *)
2 (* Abstract type of theorems and primitive inference rules. *)
4 (* John Harrison, University of Cambridge Computer Laboratory *)
6 (* (c) Copyright, University of Cambridge 1998 *)
7 (* (c) Copyright, John Harrison 1998-2007 *)
8 (* ========================================================================= *)
10 (* ------------------------------------------------------------------------- *)
11 (* A few bits of general derived syntax. *)
12 (* ------------------------------------------------------------------------- *)
17 | _ -> failwith "rator: Not a combination";;
22 | _ -> failwith "rand: Not a combination";;
24 (* ------------------------------------------------------------------------- *)
25 (* Syntax operations for equations. *)
26 (* ------------------------------------------------------------------------- *)
30 Comb(Comb(Const("=",_),l),r) -> l,r
31 | _ -> failwith "dest_eq";;
35 Comb(Comb(Const("=",_),_),_) -> true
39 let eq = mk_const("=",[]) in
41 try let ty = type_of l in
42 let eq_tm = inst [ty,aty] eq in
43 mk_comb(mk_comb(eq_tm,l),r)
44 with Failure _ -> failwith "mk_eq";;
46 (* ------------------------------------------------------------------------- *)
47 (* Useful to have term union modulo alpha-conversion for assumption lists. *)
48 (* ------------------------------------------------------------------------- *)
50 let rec ordav env x1 x2 =
52 [] -> Pervasives.compare x1 x2
53 | (t1,t2 as tp)::oenv -> if Pervasives.compare x1 t1 = 0
54 then if Pervasives.compare x2 t2 = 0
56 else if Pervasives.compare x2 t2 = 0 then 1
59 let rec orda env tm1 tm2 =
60 if tm1 == tm2 & env = [] then 0 else
62 Var(x1,ty1),Var(x2,ty2) -> ordav env tm1 tm2
63 | Const(x1,ty1),Const(x2,ty2) -> Pervasives.compare tm1 tm2
64 | Comb(s1,t1),Comb(s2,t2) ->
65 let c = orda env s1 s2 in if c <> 0 then c else orda env t1 t2
66 | Abs(Var(_,ty1) as x1,t1),Abs(Var(_,ty2) as x2,t2) ->
67 let c = Pervasives.compare ty1 ty2 in
68 if c <> 0 then c else orda ((x1,x2)::env) t1 t2
76 let alphaorder = orda []
78 let rec term_union l1 l2 =
82 | (h1::t1,h2::t2) -> let c = alphaorder h1 h2 in
83 if c = 0 then h1::(term_union t1 t2)
84 else if c < 0 then h1::(term_union t1 l2)
85 else h2::(term_union l1 t2)
87 let rec term_remove t l =
89 s::ss -> let c = alphaorder t s in
91 let ss' = term_remove t ss in
92 if ss' == ss then l else s::ss'
93 else if c = 0 then ss else l
96 let rec term_image f l =
98 h::t -> let h' = f h and t' = term_image f t in
99 if h' == h & t' == t then l else term_union [h'] t'
102 (* ------------------------------------------------------------------------- *)
103 (* The abstract type of theorems. *)
104 (* ------------------------------------------------------------------------- *)
106 module type Hol_thm_primitives =
108 val dest_thm : thm -> term list * term
109 val hyp : thm -> term list
110 val concl : thm -> term
111 val REFL : term -> thm
112 val TRANS : thm -> thm -> thm
113 val MK_COMB : thm * thm -> thm
114 val ABS : term -> thm -> thm
115 val BETA : term -> thm
116 val ASSUME : term -> thm
117 val EQ_MP : thm -> thm -> thm
118 val DEDUCT_ANTISYM_RULE : thm -> thm -> thm
119 val INST_TYPE : (hol_type * hol_type) list -> thm -> thm
120 val INST : (term * term) list -> thm -> thm
121 val axioms : unit -> thm list
122 val new_axiom : term -> thm
123 val new_basic_definition : term -> thm
124 val new_basic_type_definition : string -> string * string -> thm -> thm * thm
126 val equals_thm : thm -> thm -> bool
127 val le_thm : thm -> thm -> bool
128 val less_thm : thm -> thm -> bool
130 val proof_of : thm -> proof
131 val substitute_proof : thm -> proof -> thm
132 val save_thm : string -> thm -> thm
135 (* ------------------------------------------------------------------------- *)
136 (* This is the implementation of those primitives. *)
137 (* ------------------------------------------------------------------------- *)
139 module Hol : Hol_thm_primitives = struct
141 type thm = Sequent of (term list * term * proof)
143 (* ------------------------------------------------------------------------- *)
144 (* Basic theorem destructors. *)
145 (* ------------------------------------------------------------------------- *)
147 let dest_thm (Sequent(asl,c,_)) = (asl,c)
149 let hyp (Sequent(asl,c,_)) = asl
151 let concl (Sequent(asl,c,_)) = c
153 (* ------------------------------------------------------------------------- *)
154 (* Basic equality properties; TRANS is derivable but included for efficiency *)
155 (* ------------------------------------------------------------------------- *)
158 Sequent([],mk_eq (tm, tm), proof_REFL tm)
160 let TRANS (Sequent(asl1,c1,p1)) (Sequent(asl2,c2,p2)) =
162 Comb((Comb(Const("=",_),l) as eql),m1),Comb(Comb(Const("=",_),m2),r)
163 when alphaorder m1 m2 = 0 -> Sequent(term_union asl1 asl2,mk_comb (eql, r),proof_TRANS (p1,p2))
164 | _ -> failwith "TRANS"
166 (* ------------------------------------------------------------------------- *)
167 (* Congruence properties of equality. *)
168 (* ------------------------------------------------------------------------- *)
170 let MK_COMB(Sequent(asl1,c1,p1),Sequent(asl2,c2,p2)) =
172 Comb(Comb(Const("=",_),l1),r1),Comb(Comb(Const("=",_),l2),r2) ->
173 (match type_of l1 with
174 Tyapp("fun",[ty;_]) when Pervasives.compare ty (type_of l2) = 0
175 -> Sequent(term_union asl1 asl2,
176 mk_eq (mk_comb (l1, l2), mk_comb(r1, r2)),
177 proof_MK_COMB (p1,p2))
178 | _ -> failwith "MK_COMB: types do not agree")
179 | _ -> failwith "MK_COMB: not both equations"
181 let ABS v (Sequent(asl,c,p)) =
183 Var(_,_),Comb(Comb(Const("=",_),l),r) when not(exists (vfree_in v) asl)
184 -> Sequent(asl,mk_eq (mk_abs (v, l), mk_abs (v, r)),proof_ABS v p)
185 | _ -> failwith "ABS";;
187 (* ------------------------------------------------------------------------- *)
188 (* Trivial case of lambda calculus beta-conversion. *)
189 (* ------------------------------------------------------------------------- *)
193 Comb(Abs(v,bod),arg) when Pervasives.compare arg v = 0
194 -> Sequent([],mk_eq (tm, bod), proof_BETA tm)
195 | _ -> failwith "BETA: not a trivial beta-redex"
197 (* ------------------------------------------------------------------------- *)
198 (* Rules connected with deduction. *)
199 (* ------------------------------------------------------------------------- *)
202 if Pervasives.compare (type_of tm) bool_ty = 0 then Sequent([tm],tm, proof_ASSUME tm)
203 else failwith "ASSUME: not a proposition"
205 let EQ_MP (Sequent(asl1,eq,p1)) (Sequent(asl2,c,p2)) =
207 Comb(Comb(Const("=",_),l),r) when alphaorder l c = 0
208 -> Sequent(term_union asl1 asl2,r, proof_EQ_MP p1 p2)
209 | _ -> failwith "EQ_MP"
211 let DEDUCT_ANTISYM_RULE (Sequent(asl1,c1,p1)) (Sequent(asl2,c2,p2)) =
212 let asl1' = term_remove c2 asl1 and asl2' = term_remove c1 asl2 in
213 Sequent(term_union asl1' asl2',mk_eq (c1, c2),
214 proof_DEDUCT_ANTISYM_RULE (p1,c1) (p2,c2))
216 (* ------------------------------------------------------------------------- *)
217 (* Type and term instantiation. *)
218 (* ------------------------------------------------------------------------- *)
220 let INST_TYPE theta (Sequent(asl,c,p)) =
221 let inst_fn = inst theta in
222 Sequent(term_image inst_fn asl,inst_fn c, proof_INST_TYPE theta p)
224 let INST theta (Sequent(asl,c,p)) =
225 let inst_fun = vsubst theta in
226 Sequent(term_image inst_fun asl,inst_fun c, proof_INST theta p)
228 (* ------------------------------------------------------------------------- *)
229 (* Handling of axioms. *)
230 (* ------------------------------------------------------------------------- *)
232 let the_axioms = ref ([]:thm list)
234 let axioms() = !the_axioms
237 if Pervasives.compare (type_of tm) bool_ty = 0 then
238 let axname = new_axiom_name "" in
239 let p = proof_new_axiom (axname) tm in
240 let th = Sequent([],tm,p) in
241 (the_axioms := th::(!the_axioms);
242 save_proof axname p (Some tm);
244 else failwith "new_axiom: Not a proposition"
246 (* ------------------------------------------------------------------------- *)
247 (* Handling of (term) definitions. *)
248 (* ------------------------------------------------------------------------- *)
250 let the_definitions = ref ([]:thm list)
252 let definitions() = !the_definitions
254 let new_basic_definition tm =
256 Comb(Comb(Const("=",_),(Var(cname,ty) as l)),r) ->
257 if not(freesin [] r) then failwith "new_definition: term not closed"
258 else if not (subset (type_vars_in_term r) (tyvars ty))
259 then failwith "new_definition: Type variables not reflected in constant"
260 else let c = new_constant(cname,ty); mk_const (cname, []) in
261 let p = proof_new_definition cname ty r in
262 let concl = mk_eq (c, r) in
263 save_proof ("DEF_"^cname) p (Some concl);
264 let dth = Sequent([],concl,p) in
265 the_definitions := dth::(!the_definitions); dth
266 | _ -> failwith "new_basic_definition"
268 (* ------------------------------------------------------------------------- *)
269 (* Handling of type definitions. *)
271 (* This function now involves no logical constants beyond equality. *)
274 (* --------------------------- *)
275 (* |- abs(rep a) = a *)
276 (* |- P r = (rep(abs r) = r) *)
278 (* Where "abs" and "rep" are new constants with the nominated names. *)
279 (* ------------------------------------------------------------------------- *)
281 let new_basic_type_definition tyname (absname,repname) (Sequent(asl,c,p)) =
282 if exists (can get_const_type) [absname; repname] then
283 failwith "new_basic_type_definition: Constant(s) already in use" else
284 if not (asl = []) then
285 failwith "new_basic_type_definition: Assumptions in theorem" else
286 let P,x = try dest_comb c
288 failwith "new_basic_type_definition: Not a combination" in
289 if not(freesin [] P) then
290 failwith "new_basic_type_definition: Predicate is not closed" else
291 let tyvars = sort (<=) (type_vars_in_term P) in
292 let _ = try new_type(tyname,length tyvars)
294 failwith "new_basic_type_definition: Type already defined" in
295 let aty = mk_type(tyname,tyvars)
296 and rty = type_of x in
297 let absty = mk_type("fun",[rty;aty]) and repty = mk_type("fun",[aty;rty]) in
298 let abs = (new_constant(absname,absty); mk_const(absname,[]))
299 and rep = (new_constant(repname,repty); mk_const(repname,[])) in
300 let a = mk_var("a",aty) and r = mk_var("r",rty) in
301 let ax1 = mk_eq (mk_comb(abs,mk_comb(rep,a)), a) in
302 let ax2 = mk_eq (mk_comb(P,r),
303 mk_eq (mk_comb(rep,mk_comb(abs,r)), r)) in
304 let tp = proof_new_basic_type_definition tyname (absname, repname) (P,x) p in
305 let tname = "TYDEF_"^tyname in
306 save_proof tname tp None;
307 Sequent([],ax1,proof_CONJUNCT1 tp),
308 Sequent([],ax2,proof_CONJUNCT2 tp)
310 (* ------------------------------------------------------------------------- *)
311 (* Dealing with proof objects. *)
312 (* ------------------------------------------------------------------------- *)
314 let substitute_proof =
315 if use_extended_proofobjects then
316 fun (Sequent (asl, c, p)) pnew -> Sequent (asl, c, pnew)
320 let equals_thm (Sequent (p1,c1,_)) (Sequent (p2,c2,_)) =
321 (p1 = p2) & (c1 = c2)
323 let le_thm (Sequent (p1,c1,_)) (Sequent (p2,c2,_)) = (p1, c1) <= (p2, c2)
325 let less_thm (Sequent (p1, c1,_)) (Sequent (p2, c2,_)) = (p1, c1) < (p2, c2)
327 let proof_of (Sequent(_,_,p)) = p
329 let save_thm name th =
330 (save_proof name (proof_of th) (Some (concl th)); th)
336 (* ------------------------------------------------------------------------- *)
337 (* Tests for alpha-convertibility (equality ignoring names in abstractions). *)
338 (* ------------------------------------------------------------------------- *)
340 let aconv s t = alphaorder s t = 0;;
342 (* ------------------------------------------------------------------------- *)
343 (* Comparison function on theorems. Currently the same as equality, but *)
344 (* it's useful to separate because in the proof-recording version it isn't. *)
345 (* ------------------------------------------------------------------------- *)
347 let equals_thm th th' = dest_thm th = dest_thm th';;