55 |
55 |
56 (* Additional theorem for goals of form x ~= y *) |
56 (* Additional theorem for goals of form x ~= y *) |
57 val less_imp_neq : thm (* x < y ==> x ~= y *) |
57 val less_imp_neq : thm (* x < y ==> x ~= y *) |
58 |
58 |
59 (* Analysis of premises and conclusion *) |
59 (* Analysis of premises and conclusion *) |
60 (* decomp_x (`x Rel y') should yield Some (x, Rel, y) |
60 (* decomp_x (`x Rel y') should yield SOME (x, Rel, y) |
61 where Rel is one of "<", "<=", "=" and "~=", |
61 where Rel is one of "<", "<=", "=" and "~=", |
62 other relation symbols cause an error message *) |
62 other relation symbols cause an error message *) |
63 (* decomp_trans is used by trans_tac, it may only return Rel = "<=" *) |
63 (* decomp_trans is used by trans_tac, it may only return Rel = "<=" *) |
64 val decomp_trans: Sign.sg -> term -> (term * string * term) option |
64 val decomp_trans: Sign.sg -> term -> (term * string * term) option |
65 (* decomp_quasi is used by quasi_tac *) |
65 (* decomp_quasi is used by quasi_tac *) |
125 (* *) |
125 (* *) |
126 (* ************************************************************************ *) |
126 (* ************************************************************************ *) |
127 |
127 |
128 fun mkasm_trans sign (t, n) = |
128 fun mkasm_trans sign (t, n) = |
129 case Less.decomp_trans sign t of |
129 case Less.decomp_trans sign t of |
130 Some (x, rel, y) => |
130 SOME (x, rel, y) => |
131 (case rel of |
131 (case rel of |
132 "<=" => [Le (x, y, Asm n)] |
132 "<=" => [Le (x, y, Asm n)] |
133 | _ => error ("trans_tac: unknown relation symbol ``" ^ rel ^ |
133 | _ => error ("trans_tac: unknown relation symbol ``" ^ rel ^ |
134 "''returned by decomp_trans.")) |
134 "''returned by decomp_trans.")) |
135 | None => []; |
135 | NONE => []; |
136 |
136 |
137 (* ************************************************************************ *) |
137 (* ************************************************************************ *) |
138 (* *) |
138 (* *) |
139 (* mkasm_quasi sign (t, n) : Sign.sg -> (Term.term * int) -> less *) |
139 (* mkasm_quasi sign (t, n) : Sign.sg -> (Term.term * int) -> less *) |
140 (* *) |
140 (* *) |
144 (* *) |
144 (* *) |
145 (* ************************************************************************ *) |
145 (* ************************************************************************ *) |
146 |
146 |
147 fun mkasm_quasi sign (t, n) = |
147 fun mkasm_quasi sign (t, n) = |
148 case Less.decomp_quasi sign t of |
148 case Less.decomp_quasi sign t of |
149 Some (x, rel, y) => (case rel of |
149 SOME (x, rel, y) => (case rel of |
150 "<" => if (x aconv y) then raise Contr (Thm ([Asm n], Less.less_reflE)) |
150 "<" => if (x aconv y) then raise Contr (Thm ([Asm n], Less.less_reflE)) |
151 else [Less (x, y, Asm n)] |
151 else [Less (x, y, Asm n)] |
152 | "<=" => [Le (x, y, Asm n)] |
152 | "<=" => [Le (x, y, Asm n)] |
153 | "=" => [Le (x, y, Thm ([Asm n], Less.eqD1)), |
153 | "=" => [Le (x, y, Thm ([Asm n], Less.eqD1)), |
154 Le (y, x, Thm ([Asm n], Less.eqD2))] |
154 Le (y, x, Thm ([Asm n], Less.eqD2))] |
156 raise Contr (Thm ([(Thm ([(Thm ([], Less.le_refl)) ,(Asm n)], Less.le_neq_trans))], Less.less_reflE)) |
156 raise Contr (Thm ([(Thm ([(Thm ([], Less.le_refl)) ,(Asm n)], Less.le_neq_trans))], Less.less_reflE)) |
157 else [ NotEq (x, y, Asm n), |
157 else [ NotEq (x, y, Asm n), |
158 NotEq (y, x,Thm ( [Asm n], thm "not_sym"))] |
158 NotEq (y, x,Thm ( [Asm n], thm "not_sym"))] |
159 | _ => error ("quasi_tac: unknown relation symbol ``" ^ rel ^ |
159 | _ => error ("quasi_tac: unknown relation symbol ``" ^ rel ^ |
160 "''returned by decomp_quasi.")) |
160 "''returned by decomp_quasi.")) |
161 | None => []; |
161 | NONE => []; |
162 |
162 |
163 |
163 |
164 (* ************************************************************************ *) |
164 (* ************************************************************************ *) |
165 (* *) |
165 (* *) |
166 (* mkconcl_trans sign t : Sign.sg -> Term.term -> less *) |
166 (* mkconcl_trans sign t : Sign.sg -> Term.term -> less *) |
171 (* ************************************************************************ *) |
171 (* ************************************************************************ *) |
172 |
172 |
173 |
173 |
174 fun mkconcl_trans sign t = |
174 fun mkconcl_trans sign t = |
175 case Less.decomp_trans sign t of |
175 case Less.decomp_trans sign t of |
176 Some (x, rel, y) => (case rel of |
176 SOME (x, rel, y) => (case rel of |
177 "<=" => (Le (x, y, Asm ~1), Asm 0) |
177 "<=" => (Le (x, y, Asm ~1), Asm 0) |
178 | _ => raise Cannot) |
178 | _ => raise Cannot) |
179 | None => raise Cannot; |
179 | NONE => raise Cannot; |
180 |
180 |
181 |
181 |
182 (* ************************************************************************ *) |
182 (* ************************************************************************ *) |
183 (* *) |
183 (* *) |
184 (* mkconcl_quasi sign t : Sign.sg -> Term.term -> less *) |
184 (* mkconcl_quasi sign t : Sign.sg -> Term.term -> less *) |
188 (* *) |
188 (* *) |
189 (* ************************************************************************ *) |
189 (* ************************************************************************ *) |
190 |
190 |
191 fun mkconcl_quasi sign t = |
191 fun mkconcl_quasi sign t = |
192 case Less.decomp_quasi sign t of |
192 case Less.decomp_quasi sign t of |
193 Some (x, rel, y) => (case rel of |
193 SOME (x, rel, y) => (case rel of |
194 "<" => ([Less (x, y, Asm ~1)], Asm 0) |
194 "<" => ([Less (x, y, Asm ~1)], Asm 0) |
195 | "<=" => ([Le (x, y, Asm ~1)], Asm 0) |
195 | "<=" => ([Le (x, y, Asm ~1)], Asm 0) |
196 | "~=" => ([NotEq (x,y, Asm ~1)], Asm 0) |
196 | "~=" => ([NotEq (x,y, Asm ~1)], Asm 0) |
197 | _ => raise Cannot) |
197 | _ => raise Cannot) |
198 | None => raise Cannot; |
198 | NONE => raise Cannot; |
199 |
199 |
200 |
200 |
201 (* ******************************************************************* *) |
201 (* ******************************************************************* *) |
202 (* *) |
202 (* *) |
203 (* mergeLess (less1,less2): less * less -> less *) |
203 (* mergeLess (less1,less2): less * less -> less *) |
264 | (NotEq(x,y,_)) subsumes (NotEq(x',y',_)) = x aconv x' andalso y aconv y' orelse x aconv y' andalso y aconv x' |
264 | (NotEq(x,y,_)) subsumes (NotEq(x',y',_)) = x aconv x' andalso y aconv y' orelse x aconv y' andalso y aconv x' |
265 | _ subsumes _ = false; |
265 | _ subsumes _ = false; |
266 |
266 |
267 (* ******************************************************************* *) |
267 (* ******************************************************************* *) |
268 (* *) |
268 (* *) |
269 (* triv_solv less1 : less -> proof Library.option *) |
269 (* triv_solv less1 : less -> proof option *) |
270 (* *) |
270 (* *) |
271 (* Solves trivial goal x <= x. *) |
271 (* Solves trivial goal x <= x. *) |
272 (* *) |
272 (* *) |
273 (* ******************************************************************* *) |
273 (* ******************************************************************* *) |
274 |
274 |
275 fun triv_solv (Le (x, x', _)) = |
275 fun triv_solv (Le (x, x', _)) = |
276 if x aconv x' then Some (Thm ([], Less.le_refl)) |
276 if x aconv x' then SOME (Thm ([], Less.le_refl)) |
277 else None |
277 else NONE |
278 | triv_solv _ = None; |
278 | triv_solv _ = NONE; |
279 |
279 |
280 (* ********************************************************************* *) |
280 (* ********************************************************************* *) |
281 (* Graph functions *) |
281 (* Graph functions *) |
282 (* ********************************************************************* *) |
282 (* ********************************************************************* *) |
283 |
283 |
461 in getprf Le_x_y end ) |
461 in getprf Le_x_y end ) |
462 else raise Cannot |
462 else raise Cannot |
463 end ) |
463 end ) |
464 | (Less (x,y,_)) => ( |
464 | (Less (x,y,_)) => ( |
465 let |
465 let |
466 fun findParallelNeq [] = None |
466 fun findParallelNeq [] = NONE |
467 | findParallelNeq (e::es) = |
467 | findParallelNeq (e::es) = |
468 if (x aconv (lower e) andalso y aconv (upper e)) then Some e |
468 if (x aconv (lower e) andalso y aconv (upper e)) then SOME e |
469 else if (y aconv (lower e) andalso x aconv (upper e)) then Some (NotEq (x,y, (Thm ([getprf e], thm "not_sym")))) |
469 else if (y aconv (lower e) andalso x aconv (upper e)) then SOME (NotEq (x,y, (Thm ([getprf e], thm "not_sym")))) |
470 else findParallelNeq es ; |
470 else findParallelNeq es ; |
471 in |
471 in |
472 (* test if there is a edge x ~= y respectivly y ~= x and *) |
472 (* test if there is a edge x ~= y respectivly y ~= x and *) |
473 (* if it possible to find a path x <= y in leG, thus we can conclude x < y *) |
473 (* if it possible to find a path x <= y in leG, thus we can conclude x < y *) |
474 (case findParallelNeq neqE of (Some e) => |
474 (case findParallelNeq neqE of (SOME e) => |
475 let |
475 let |
476 val (xyLeFound,xyLePath) = findPath x y leG |
476 val (xyLeFound,xyLePath) = findPath x y leG |
477 in |
477 in |
478 if xyLeFound then ( |
478 if xyLeFound then ( |
479 let |
479 let |
485 | _ => raise Cannot) |
485 | _ => raise Cannot) |
486 end ) |
486 end ) |
487 | (NotEq (x,y,_)) => |
487 | (NotEq (x,y,_)) => |
488 (* First check if a single premiss is sufficient *) |
488 (* First check if a single premiss is sufficient *) |
489 (case (Library.find_first (fn fact => fact subsumes subgoal) neqE, subgoal) of |
489 (case (Library.find_first (fn fact => fact subsumes subgoal) neqE, subgoal) of |
490 (Some (NotEq (x, y, p)), NotEq (x', y', _)) => |
490 (SOME (NotEq (x, y, p)), NotEq (x', y', _)) => |
491 if (x aconv x' andalso y aconv y') then p |
491 if (x aconv x' andalso y aconv y') then p |
492 else Thm ([p], thm "not_sym") |
492 else Thm ([p], thm "not_sym") |
493 | _ => raise Cannot |
493 | _ => raise Cannot |
494 ) |
494 ) |
495 |
495 |
538 val (leG, neqE) = mkQuasiGraph asms |
538 val (leG, neqE) = mkQuasiGraph asms |
539 in |
539 in |
540 let |
540 let |
541 val (subgoals, prf) = mkconcl_quasi sign concl |
541 val (subgoals, prf) = mkconcl_quasi sign concl |
542 fun solve facts less = |
542 fun solve facts less = |
543 (case triv_solv less of None => findQuasiProof (leG, neqE) less |
543 (case triv_solv less of NONE => findQuasiProof (leG, neqE) less |
544 | Some prf => prf ) |
544 | SOME prf => prf ) |
545 in map (solve asms) subgoals end |
545 in map (solve asms) subgoals end |
546 end; |
546 end; |
547 |
547 |
548 (* ************************************************************************ *) |
548 (* ************************************************************************ *) |
549 (* *) |
549 (* *) |