1 (* ========================================================================= *) |
1 (* ========================================================================= *) |
2 (* DERIVED RULES FOR CREATING FIRST ORDER LOGIC THEOREMS *) |
2 (* DERIVED RULES FOR CREATING FIRST ORDER LOGIC THEOREMS *) |
3 (* Copyright (c) 2001-2006 Joe Hurd, distributed under the BSD License *) |
3 (* Copyright (c) 2001-2006 Joe Hurd, distributed under the BSD License *) |
4 (* ========================================================================= *) |
4 (* ========================================================================= *) |
5 |
5 |
6 structure Rule :> Rule = |
6 structure Rule :> Rule = |
7 struct |
7 struct |
8 |
8 |
9 open Useful; |
9 open Useful; |
10 |
10 |
11 (* ------------------------------------------------------------------------- *) |
11 (* ------------------------------------------------------------------------- *) |
|
12 (* Variable names. *) |
|
13 (* ------------------------------------------------------------------------- *) |
|
14 |
|
15 val xVarName = Name.fromString "x"; |
|
16 val xVar = Term.Var xVarName; |
|
17 |
|
18 val yVarName = Name.fromString "y"; |
|
19 val yVar = Term.Var yVarName; |
|
20 |
|
21 val zVarName = Name.fromString "z"; |
|
22 val zVar = Term.Var zVarName; |
|
23 |
|
24 fun xIVarName i = Name.fromString ("x" ^ Int.toString i); |
|
25 fun xIVar i = Term.Var (xIVarName i); |
|
26 |
|
27 fun yIVarName i = Name.fromString ("y" ^ Int.toString i); |
|
28 fun yIVar i = Term.Var (yIVarName i); |
|
29 |
|
30 (* ------------------------------------------------------------------------- *) |
12 (* *) |
31 (* *) |
13 (* --------- reflexivity *) |
32 (* --------- reflexivity *) |
14 (* x = x *) |
33 (* x = x *) |
15 (* ------------------------------------------------------------------------- *) |
34 (* ------------------------------------------------------------------------- *) |
16 |
35 |
17 val reflexivity = Thm.refl (Term.Var "x"); |
36 fun reflexivityRule x = Thm.refl x; |
|
37 |
|
38 val reflexivity = reflexivityRule xVar; |
18 |
39 |
19 (* ------------------------------------------------------------------------- *) |
40 (* ------------------------------------------------------------------------- *) |
20 (* *) |
41 (* *) |
21 (* --------------------- symmetry *) |
42 (* --------------------- symmetry *) |
22 (* ~(x = y) \/ y = x *) |
43 (* ~(x = y) \/ y = x *) |
23 (* ------------------------------------------------------------------------- *) |
44 (* ------------------------------------------------------------------------- *) |
24 |
45 |
25 val symmetry = |
46 fun symmetryRule x y = |
26 let |
47 let |
27 val x = Term.Var "x" |
48 val reflTh = reflexivityRule x |
28 and y = Term.Var "y" |
|
29 val reflTh = reflexivity |
|
30 val reflLit = Thm.destUnit reflTh |
49 val reflLit = Thm.destUnit reflTh |
31 val eqTh = Thm.equality reflLit [0] y |
50 val eqTh = Thm.equality reflLit [0] y |
32 in |
51 in |
33 Thm.resolve reflLit reflTh eqTh |
52 Thm.resolve reflLit reflTh eqTh |
34 end; |
53 end; |
35 |
54 |
|
55 val symmetry = symmetryRule xVar yVar; |
|
56 |
36 (* ------------------------------------------------------------------------- *) |
57 (* ------------------------------------------------------------------------- *) |
37 (* *) |
58 (* *) |
38 (* --------------------------------- transitivity *) |
59 (* --------------------------------- transitivity *) |
39 (* ~(x = y) \/ ~(y = z) \/ x = z *) |
60 (* ~(x = y) \/ ~(y = z) \/ x = z *) |
40 (* ------------------------------------------------------------------------- *) |
61 (* ------------------------------------------------------------------------- *) |
41 |
62 |
42 val transitivity = |
63 val transitivity = |
43 let |
64 let |
44 val x = Term.Var "x" |
65 val eqTh = Thm.equality (Literal.mkEq (yVar,zVar)) [0] xVar |
45 and y = Term.Var "y" |
66 in |
46 and z = Term.Var "z" |
67 Thm.resolve (Literal.mkEq (yVar,xVar)) symmetry eqTh |
47 val eqTh = Thm.equality (Literal.mkEq (y,z)) [0] x |
|
48 in |
|
49 Thm.resolve (Literal.mkEq (y,x)) symmetry eqTh |
|
50 end; |
68 end; |
51 |
69 |
52 (* ------------------------------------------------------------------------- *) |
70 (* ------------------------------------------------------------------------- *) |
53 (* x = y \/ C *) |
71 (* x = y \/ C *) |
54 (* -------------- symEq (x = y) *) |
72 (* -------------- symEq (x = y) *) |
88 end; |
106 end; |
89 |
107 |
90 fun reflEqn t = ((t,t), Thm.refl t); |
108 fun reflEqn t = ((t,t), Thm.refl t); |
91 |
109 |
92 fun symEqn (eqn as ((t,u), th)) = |
110 fun symEqn (eqn as ((t,u), th)) = |
93 if t = u then eqn |
111 if Term.equal t u then eqn |
94 else |
112 else |
95 ((u,t), |
113 ((u,t), |
96 case equationLiteral eqn of |
114 case equationLiteral eqn of |
97 SOME t_u => symEq t_u th |
115 SOME t_u => symEq t_u th |
98 | NONE => th); |
116 | NONE => th); |
99 |
117 |
100 fun transEqn (eqn1 as ((x,y), th1)) (eqn2 as ((_,z), th2)) = |
118 fun transEqn (eqn1 as ((x,y), th1)) (eqn2 as ((_,z), th2)) = |
101 if x = y then eqn2 |
119 if Term.equal x y then eqn2 |
102 else if y = z then eqn1 |
120 else if Term.equal y z then eqn1 |
103 else if x = z then reflEqn x |
121 else if Term.equal x z then reflEqn x |
104 else |
122 else |
105 ((x,z), |
123 ((x,z), |
106 case equationLiteral eqn1 of |
124 case equationLiteral eqn1 of |
107 NONE => th1 |
125 NONE => th1 |
108 | SOME x_y => |
126 | SOME x_y => |
109 case equationLiteral eqn2 of |
127 case equationLiteral eqn2 of |
110 NONE => th2 |
128 NONE => th2 |
111 | SOME y_z => |
129 | SOME y_z => |
112 let |
130 let |
113 val sub = Subst.fromList [("x",x),("y",y),("z",z)] |
131 val sub = Subst.fromList [(xVarName,x),(yVarName,y),(zVarName,z)] |
114 val th = Thm.subst sub transitivity |
132 val th = Thm.subst sub transitivity |
115 val th = Thm.resolve x_y th1 th |
133 val th = Thm.resolve x_y th1 th |
116 val th = Thm.resolve y_z th2 th |
134 val th = Thm.resolve y_z th2 th |
117 in |
135 in |
118 th |
136 th |
119 end); |
137 end); |
120 |
138 |
121 (*DEBUG |
139 (*MetisDebug |
122 val transEqn = fn eqn1 => fn eqn2 => |
140 val transEqn = fn eqn1 => fn eqn2 => |
123 transEqn eqn1 eqn2 |
141 transEqn eqn1 eqn2 |
124 handle Error err => |
142 handle Error err => |
125 raise Error ("Rule.transEqn:\neqn1 = " ^ equationToString eqn1 ^ |
143 raise Error ("Rule.transEqn:\neqn1 = " ^ equationToString eqn1 ^ |
126 "\neqn2 = " ^ equationToString eqn2 ^ "\n" ^ err); |
144 "\neqn2 = " ^ equationToString eqn2 ^ "\n" ^ err); |
147 res |
165 res |
148 end |
166 end |
149 handle Error err => |
167 handle Error err => |
150 (print (s ^ ": " ^ Term.toString tm ^ " --> Error: " ^ err ^ "\n"); |
168 (print (s ^ ": " ^ Term.toString tm ^ " --> Error: " ^ err ^ "\n"); |
151 raise Error (s ^ ": " ^ err)); |
169 raise Error (s ^ ": " ^ err)); |
152 |
170 |
153 fun thenConvTrans tm (tm',th1) (tm'',th2) = |
171 fun thenConvTrans tm (tm',th1) (tm'',th2) = |
154 let |
172 let |
155 val eqn1 = ((tm,tm'),th1) |
173 val eqn1 = ((tm,tm'),th1) |
156 and eqn2 = ((tm',tm''),th2) |
174 and eqn2 = ((tm',tm''),th2) |
157 val (_,th) = transEqn eqn1 eqn2 |
175 val (_,th) = transEqn eqn1 eqn2 |
187 fun everyConv [] tm = allConv tm |
205 fun everyConv [] tm = allConv tm |
188 | everyConv [conv] tm = conv tm |
206 | everyConv [conv] tm = conv tm |
189 | everyConv (conv :: convs) tm = thenConv conv (everyConv convs) tm; |
207 | everyConv (conv :: convs) tm = thenConv conv (everyConv convs) tm; |
190 |
208 |
191 fun rewrConv (eqn as ((x,y), eqTh)) path tm = |
209 fun rewrConv (eqn as ((x,y), eqTh)) path tm = |
192 if x = y then allConv tm |
210 if Term.equal x y then allConv tm |
193 else if null path then (y,eqTh) |
211 else if null path then (y,eqTh) |
194 else |
212 else |
195 let |
213 let |
196 val reflTh = Thm.refl tm |
214 val reflTh = Thm.refl tm |
197 val reflLit = Thm.destUnit reflTh |
215 val reflLit = Thm.destUnit reflTh |
271 fun thenLiterule literule1 literule2 lit = |
289 fun thenLiterule literule1 literule2 lit = |
272 let |
290 let |
273 val res1 as (lit',th1) = literule1 lit |
291 val res1 as (lit',th1) = literule1 lit |
274 val res2 as (lit'',th2) = literule2 lit' |
292 val res2 as (lit'',th2) = literule2 lit' |
275 in |
293 in |
276 if lit = lit' then res2 |
294 if Literal.equal lit lit' then res2 |
277 else if lit' = lit'' then res1 |
295 else if Literal.equal lit' lit'' then res1 |
278 else if lit = lit'' then allLiterule lit |
296 else if Literal.equal lit lit'' then allLiterule lit |
279 else |
297 else |
280 (lit'', |
298 (lit'', |
281 if not (Thm.member lit' th1) then th1 |
299 if not (Thm.member lit' th1) then th1 |
282 else if not (Thm.negateMember lit' th2) then th2 |
300 else if not (Thm.negateMember lit' th2) then th2 |
283 else Thm.resolve lit' th1 th2) |
301 else Thm.resolve lit' th1 th2) |
307 | everyLiterule [literule] lit = literule lit |
325 | everyLiterule [literule] lit = literule lit |
308 | everyLiterule (literule :: literules) lit = |
326 | everyLiterule (literule :: literules) lit = |
309 thenLiterule literule (everyLiterule literules) lit; |
327 thenLiterule literule (everyLiterule literules) lit; |
310 |
328 |
311 fun rewrLiterule (eqn as ((x,y),eqTh)) path lit = |
329 fun rewrLiterule (eqn as ((x,y),eqTh)) path lit = |
312 if x = y then allLiterule lit |
330 if Term.equal x y then allLiterule lit |
313 else |
331 else |
314 let |
332 let |
315 val th = Thm.equality lit path y |
333 val th = Thm.equality lit path y |
316 val th = |
334 val th = |
317 case equationLiteral eqn of |
335 case equationLiteral eqn of |
382 |
400 |
383 fun literalRule literule lit th = |
401 fun literalRule literule lit th = |
384 let |
402 let |
385 val (lit',litTh) = literule lit |
403 val (lit',litTh) = literule lit |
386 in |
404 in |
387 if lit = lit' then th |
405 if Literal.equal lit lit' then th |
388 else if not (Thm.negateMember lit litTh) then litTh |
406 else if not (Thm.negateMember lit litTh) then litTh |
389 else Thm.resolve lit th litTh |
407 else Thm.resolve lit th litTh |
390 end; |
408 end; |
391 |
409 |
392 (*DEBUG |
410 (*MetisDebug |
393 val literalRule = fn literule => fn lit => fn th => |
411 val literalRule = fn literule => fn lit => fn th => |
394 literalRule literule lit th |
412 literalRule literule lit th |
395 handle Error err => |
413 handle Error err => |
396 raise Error ("Rule.literalRule:\nlit = " ^ Literal.toString lit ^ |
414 raise Error ("Rule.literalRule:\nlit = " ^ Literal.toString lit ^ |
397 "\nth = " ^ Thm.toString th ^ "\n" ^ err); |
415 "\nth = " ^ Thm.toString th ^ "\n" ^ err); |
410 end; |
428 end; |
411 |
429 |
412 fun allLiteralsRule literule th = literalsRule literule (Thm.clause th) th; |
430 fun allLiteralsRule literule th = literalsRule literule (Thm.clause th) th; |
413 |
431 |
414 fun convRule conv = allLiteralsRule (allArgumentsLiterule conv); |
432 fun convRule conv = allLiteralsRule (allArgumentsLiterule conv); |
415 |
433 |
416 (* ------------------------------------------------------------------------- *) |
434 (* ------------------------------------------------------------------------- *) |
417 (* *) |
435 (* *) |
418 (* ---------------------------------------------- functionCongruence (f,n) *) |
436 (* ---------------------------------------------- functionCongruence (f,n) *) |
419 (* ~(x0 = y0) \/ ... \/ ~(x{n-1} = y{n-1}) \/ *) |
437 (* ~(x0 = y0) \/ ... \/ ~(x{n-1} = y{n-1}) \/ *) |
420 (* f x0 ... x{n-1} = f y0 ... y{n-1} *) |
438 (* f x0 ... x{n-1} = f y0 ... y{n-1} *) |
421 (* ------------------------------------------------------------------------- *) |
439 (* ------------------------------------------------------------------------- *) |
422 |
440 |
423 fun functionCongruence (f,n) = |
441 fun functionCongruence (f,n) = |
424 let |
442 let |
425 val xs = List.tabulate (n, fn i => Term.Var ("x" ^ Int.toString i)) |
443 val xs = List.tabulate (n,xIVar) |
426 and ys = List.tabulate (n, fn i => Term.Var ("y" ^ Int.toString i)) |
444 and ys = List.tabulate (n,yIVar) |
427 |
445 |
428 fun cong ((i,yi),(th,lit)) = |
446 fun cong ((i,yi),(th,lit)) = |
429 let |
447 let |
430 val path = [1,i] |
448 val path = [1,i] |
431 val th = Thm.resolve lit th (Thm.equality lit path yi) |
449 val th = Thm.resolve lit th (Thm.equality lit path yi) |
447 (* ~R x0 ... x{n-1} \/ R y0 ... y{n-1} *) |
465 (* ~R x0 ... x{n-1} \/ R y0 ... y{n-1} *) |
448 (* ------------------------------------------------------------------------- *) |
466 (* ------------------------------------------------------------------------- *) |
449 |
467 |
450 fun relationCongruence (R,n) = |
468 fun relationCongruence (R,n) = |
451 let |
469 let |
452 val xs = List.tabulate (n, fn i => Term.Var ("x" ^ Int.toString i)) |
470 val xs = List.tabulate (n,xIVar) |
453 and ys = List.tabulate (n, fn i => Term.Var ("y" ^ Int.toString i)) |
471 and ys = List.tabulate (n,yIVar) |
454 |
472 |
455 fun cong ((i,yi),(th,lit)) = |
473 fun cong ((i,yi),(th,lit)) = |
456 let |
474 let |
457 val path = [i] |
475 val path = [i] |
458 val th = Thm.resolve lit th (Thm.equality lit path yi) |
476 val th = Thm.resolve lit th (Thm.equality lit path yi) |
543 |
561 |
544 local |
562 local |
545 fun expand lit = |
563 fun expand lit = |
546 let |
564 let |
547 val (x,y) = Literal.destNeq lit |
565 val (x,y) = Literal.destNeq lit |
548 in |
566 val _ = Term.isTypedVar x orelse Term.isTypedVar y orelse |
549 if (Term.isTypedVar x orelse Term.isTypedVar y) andalso x <> y then |
567 raise Error "Rule.expandAbbrevs: no vars" |
550 Subst.unify Subst.empty x y |
568 val _ = not (Term.equal x y) orelse |
551 else raise Error "expand" |
569 raise Error "Rule.expandAbbrevs: equal vars" |
|
570 in |
|
571 Subst.unify Subst.empty x y |
552 end; |
572 end; |
553 in |
573 in |
554 fun expandAbbrevs th = |
574 fun expandAbbrevs th = |
555 case LiteralSet.firstl (total expand) (Thm.clause th) of |
575 case LiteralSet.firstl (total expand) (Thm.clause th) of |
556 NONE => removeIrrefl th |
576 NONE => removeIrrefl th |
730 fact acc others |
750 fact acc others |
731 end; |
751 end; |
732 in |
752 in |
733 fun factor' cl = |
753 fun factor' cl = |
734 let |
754 let |
735 (*TRACE6 |
755 (*MetisTrace6 |
736 val () = Parser.ppTrace LiteralSet.pp "Rule.factor': cl" cl |
756 val () = Print.trace LiteralSet.pp "Rule.factor': cl" cl |
737 *) |
757 *) |
738 val edges = mk_edges [] [] (LiteralSet.toList cl) |
758 val edges = mk_edges [] [] (LiteralSet.toList cl) |
739 (*TRACE6 |
759 (*MetisTrace6 |
740 val ppEdgesSize = Parser.ppMap length Parser.ppInt |
760 val ppEdgesSize = Print.ppMap length Print.ppInt |
741 val ppEdgel = Parser.ppList ppEdge |
761 val ppEdgel = Print.ppList ppEdge |
742 val ppEdges = Parser.ppList (Parser.ppTriple ppEdgel Subst.pp ppEdgel) |
762 val ppEdges = Print.ppList (Print.ppTriple ppEdgel Subst.pp ppEdgel) |
743 val () = Parser.ppTrace ppEdgesSize "Rule.factor': |edges|" edges |
763 val () = Print.trace ppEdgesSize "Rule.factor': |edges|" edges |
744 val () = Parser.ppTrace ppEdges "Rule.factor': edges" edges |
764 val () = Print.trace ppEdges "Rule.factor': edges" edges |
745 *) |
765 *) |
746 val result = fact [] edges |
766 val result = fact [] edges |
747 (*TRACE6 |
767 (*MetisTrace6 |
748 val ppResult = Parser.ppList Subst.pp |
768 val ppResult = Print.ppList Subst.pp |
749 val () = Parser.ppTrace ppResult "Rule.factor': result" result |
769 val () = Print.trace ppResult "Rule.factor': result" result |
750 *) |
770 *) |
751 in |
771 in |
752 result |
772 result |
753 end; |
773 end; |
754 end; |
774 end; |