136 |
136 |
137 returns either (SOME term, associated multiplicity) or (NONE, constant) |
137 returns either (SOME term, associated multiplicity) or (NONE, constant) |
138 *) |
138 *) |
139 fun demult (inj_consts : (string * typ) list) : term * Rat.rat -> term option * Rat.rat = |
139 fun demult (inj_consts : (string * typ) list) : term * Rat.rat -> term option * Rat.rat = |
140 let |
140 let |
141 fun demult ((mC as Const (@{const_name HOL.times}, _)) $ s $ t, m) = |
141 fun demult ((mC as Const (@{const_name Algebras.times}, _)) $ s $ t, m) = |
142 (case s of Const (@{const_name HOL.times}, _) $ s1 $ s2 => |
142 (case s of Const (@{const_name Algebras.times}, _) $ s1 $ s2 => |
143 (* bracketing to the right: '(s1 * s2) * t' becomes 's1 * (s2 * t)' *) |
143 (* bracketing to the right: '(s1 * s2) * t' becomes 's1 * (s2 * t)' *) |
144 demult (mC $ s1 $ (mC $ s2 $ t), m) |
144 demult (mC $ s1 $ (mC $ s2 $ t), m) |
145 | _ => |
145 | _ => |
146 (* product 's * t', where either factor can be 'NONE' *) |
146 (* product 's * t', where either factor can be 'NONE' *) |
147 (case demult (s, m) of |
147 (case demult (s, m) of |
148 (SOME s', m') => |
148 (SOME s', m') => |
149 (case demult (t, m') of |
149 (case demult (t, m') of |
150 (SOME t', m'') => (SOME (mC $ s' $ t'), m'') |
150 (SOME t', m'') => (SOME (mC $ s' $ t'), m'') |
151 | (NONE, m'') => (SOME s', m'')) |
151 | (NONE, m'') => (SOME s', m'')) |
152 | (NONE, m') => demult (t, m'))) |
152 | (NONE, m') => demult (t, m'))) |
153 | demult ((mC as Const (@{const_name HOL.divide}, _)) $ s $ t, m) = |
153 | demult ((mC as Const (@{const_name Algebras.divide}, _)) $ s $ t, m) = |
154 (* FIXME: Shouldn't we simplify nested quotients, e.g. '(s/t)/u' could |
154 (* FIXME: Shouldn't we simplify nested quotients, e.g. '(s/t)/u' could |
155 become 's/(t*u)', and '(s*t)/u' could become 's*(t/u)' ? Note that |
155 become 's/(t*u)', and '(s*t)/u' could become 's*(t/u)' ? Note that |
156 if we choose to do so here, the simpset used by arith must be able to |
156 if we choose to do so here, the simpset used by arith must be able to |
157 perform the same simplifications. *) |
157 perform the same simplifications. *) |
158 (* FIXME: Currently we treat the numerator as atomic unless the |
158 (* FIXME: Currently we treat the numerator as atomic unless the |
168 (* Note: will raise Rat.DIVZERO iff m' is Rat.zero *) |
168 (* Note: will raise Rat.DIVZERO iff m' is Rat.zero *) |
169 (case demult (t, Rat.one) of |
169 (case demult (t, Rat.one) of |
170 (SOME _, _) => (SOME (mC $ s $ t), m) |
170 (SOME _, _) => (SOME (mC $ s $ t), m) |
171 | (NONE, m') => apsnd (Rat.mult (Rat.inv m')) (demult (s, m))) |
171 | (NONE, m') => apsnd (Rat.mult (Rat.inv m')) (demult (s, m))) |
172 (* terms that evaluate to numeric constants *) |
172 (* terms that evaluate to numeric constants *) |
173 | demult (Const (@{const_name HOL.uminus}, _) $ t, m) = demult (t, Rat.neg m) |
173 | demult (Const (@{const_name Algebras.uminus}, _) $ t, m) = demult (t, Rat.neg m) |
174 | demult (Const (@{const_name HOL.zero}, _), m) = (NONE, Rat.zero) |
174 | demult (Const (@{const_name Algebras.zero}, _), m) = (NONE, Rat.zero) |
175 | demult (Const (@{const_name HOL.one}, _), m) = (NONE, m) |
175 | demult (Const (@{const_name Algebras.one}, _), m) = (NONE, m) |
176 (*Warning: in rare cases number_of encloses a non-numeral, |
176 (*Warning: in rare cases number_of encloses a non-numeral, |
177 in which case dest_numeral raises TERM; hence all the handles below. |
177 in which case dest_numeral raises TERM; hence all the handles below. |
178 Same for Suc-terms that turn out not to be numerals - |
178 Same for Suc-terms that turn out not to be numerals - |
179 although the simplifier should eliminate those anyway ...*) |
179 although the simplifier should eliminate those anyway ...*) |
180 | demult (t as Const ("Int.number_class.number_of", _) $ n, m) = |
180 | demult (t as Const ("Int.number_class.number_of", _) $ n, m) = |
194 ((term * Rat.rat) list * Rat.rat * string * (term * Rat.rat) list * Rat.rat) option = |
194 ((term * Rat.rat) list * Rat.rat * string * (term * Rat.rat) list * Rat.rat) option = |
195 let |
195 let |
196 (* Turns a term 'all' and associated multiplicity 'm' into a list 'p' of |
196 (* Turns a term 'all' and associated multiplicity 'm' into a list 'p' of |
197 summands and associated multiplicities, plus a constant 'i' (with implicit |
197 summands and associated multiplicities, plus a constant 'i' (with implicit |
198 multiplicity 1) *) |
198 multiplicity 1) *) |
199 fun poly (Const (@{const_name HOL.plus}, _) $ s $ t, |
199 fun poly (Const (@{const_name Algebras.plus}, _) $ s $ t, |
200 m : Rat.rat, pi : (term * Rat.rat) list * Rat.rat) = poly (s, m, poly (t, m, pi)) |
200 m : Rat.rat, pi : (term * Rat.rat) list * Rat.rat) = poly (s, m, poly (t, m, pi)) |
201 | poly (all as Const (@{const_name HOL.minus}, T) $ s $ t, m, pi) = |
201 | poly (all as Const (@{const_name Algebras.minus}, T) $ s $ t, m, pi) = |
202 if nT T then add_atom all m pi else poly (s, m, poly (t, Rat.neg m, pi)) |
202 if nT T then add_atom all m pi else poly (s, m, poly (t, Rat.neg m, pi)) |
203 | poly (all as Const (@{const_name HOL.uminus}, T) $ t, m, pi) = |
203 | poly (all as Const (@{const_name Algebras.uminus}, T) $ t, m, pi) = |
204 if nT T then add_atom all m pi else poly (t, Rat.neg m, pi) |
204 if nT T then add_atom all m pi else poly (t, Rat.neg m, pi) |
205 | poly (Const (@{const_name HOL.zero}, _), _, pi) = |
205 | poly (Const (@{const_name Algebras.zero}, _), _, pi) = |
206 pi |
206 pi |
207 | poly (Const (@{const_name HOL.one}, _), m, (p, i)) = |
207 | poly (Const (@{const_name Algebras.one}, _), m, (p, i)) = |
208 (p, Rat.add i m) |
208 (p, Rat.add i m) |
209 | poly (Const (@{const_name Suc}, _) $ t, m, (p, i)) = |
209 | poly (Const (@{const_name Suc}, _) $ t, m, (p, i)) = |
210 poly (t, m, (p, Rat.add i m)) |
210 poly (t, m, (p, Rat.add i m)) |
211 | poly (all as Const (@{const_name HOL.times}, _) $ _ $ _, m, pi as (p, i)) = |
211 | poly (all as Const (@{const_name Algebras.times}, _) $ _ $ _, m, pi as (p, i)) = |
212 (case demult inj_consts (all, m) of |
212 (case demult inj_consts (all, m) of |
213 (NONE, m') => (p, Rat.add i m') |
213 (NONE, m') => (p, Rat.add i m') |
214 | (SOME u, m') => add_atom u m' pi) |
214 | (SOME u, m') => add_atom u m' pi) |
215 | poly (all as Const (@{const_name HOL.divide}, _) $ _ $ _, m, pi as (p, i)) = |
215 | poly (all as Const (@{const_name Algebras.divide}, _) $ _ $ _, m, pi as (p, i)) = |
216 (case demult inj_consts (all, m) of |
216 (case demult inj_consts (all, m) of |
217 (NONE, m') => (p, Rat.add i m') |
217 (NONE, m') => (p, Rat.add i m') |
218 | (SOME u, m') => add_atom u m' pi) |
218 | (SOME u, m') => add_atom u m' pi) |
219 | poly (all as Const ("Int.number_class.number_of", Type(_,[_,T])) $ t, m, pi as (p, i)) = |
219 | poly (all as Const ("Int.number_class.number_of", Type(_,[_,T])) $ t, m, pi as (p, i)) = |
220 (let val k = HOLogic.dest_numeral t |
220 (let val k = HOLogic.dest_numeral t |
227 add_atom all m pi |
227 add_atom all m pi |
228 val (p, i) = poly (lhs, Rat.one, ([], Rat.zero)) |
228 val (p, i) = poly (lhs, Rat.one, ([], Rat.zero)) |
229 val (q, j) = poly (rhs, Rat.one, ([], Rat.zero)) |
229 val (q, j) = poly (rhs, Rat.one, ([], Rat.zero)) |
230 in |
230 in |
231 case rel of |
231 case rel of |
232 @{const_name HOL.less} => SOME (p, i, "<", q, j) |
232 @{const_name Algebras.less} => SOME (p, i, "<", q, j) |
233 | @{const_name HOL.less_eq} => SOME (p, i, "<=", q, j) |
233 | @{const_name Algebras.less_eq} => SOME (p, i, "<=", q, j) |
234 | "op =" => SOME (p, i, "=", q, j) |
234 | "op =" => SOME (p, i, "=", q, j) |
235 | _ => NONE |
235 | _ => NONE |
236 end handle Rat.DIVZERO => NONE; |
236 end handle Rat.DIVZERO => NONE; |
237 |
237 |
238 fun of_lin_arith_sort thy U = |
238 fun of_lin_arith_sort thy U = |
290 case concl_of thm of _ $ (_ $ (_ $ lhs) $ _) => ( |
290 case concl_of thm of _ $ (_ $ (_ $ lhs) $ _) => ( |
291 (* Trueprop $ ((op =) $ (?P $ lhs) $ rhs) *) |
291 (* Trueprop $ ((op =) $ (?P $ lhs) $ rhs) *) |
292 case head_of lhs of |
292 case head_of lhs of |
293 Const (a, _) => member (op =) [@{const_name Orderings.max}, |
293 Const (a, _) => member (op =) [@{const_name Orderings.max}, |
294 @{const_name Orderings.min}, |
294 @{const_name Orderings.min}, |
295 @{const_name HOL.abs}, |
295 @{const_name Algebras.abs}, |
296 @{const_name HOL.minus}, |
296 @{const_name Algebras.minus}, |
297 "Int.nat", |
297 "Int.nat" (*DYNAMIC BINDING!*), |
298 "Divides.div_class.mod", |
298 "Divides.div_class.mod" (*DYNAMIC BINDING!*), |
299 "Divides.div_class.div"] a |
299 "Divides.div_class.div" (*DYNAMIC BINDING!*)] a |
300 | _ => (warning ("Lin. Arith.: wrong format for split rule " ^ |
300 | _ => (warning ("Lin. Arith.: wrong format for split rule " ^ |
301 Display.string_of_thm_without_context thm); |
301 Display.string_of_thm_without_context thm); |
302 false)) |
302 false)) |
303 | _ => (warning ("Lin. Arith.: wrong format for split rule " ^ |
303 | _ => (warning ("Lin. Arith.: wrong format for split rule " ^ |
304 Display.string_of_thm_without_context thm); |
304 Display.string_of_thm_without_context thm); |
370 (Const (@{const_name Orderings.max}, _), [t1, t2]) => |
370 (Const (@{const_name Orderings.max}, _), [t1, t2]) => |
371 let |
371 let |
372 val rev_terms = rev terms |
372 val rev_terms = rev terms |
373 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
373 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
374 val terms2 = map (subst_term [(split_term, t2)]) rev_terms |
374 val terms2 = map (subst_term [(split_term, t2)]) rev_terms |
375 val t1_leq_t2 = Const (@{const_name HOL.less_eq}, |
375 val t1_leq_t2 = Const (@{const_name Algebras.less_eq}, |
376 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
376 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
377 val not_t1_leq_t2 = HOLogic.Not $ t1_leq_t2 |
377 val not_t1_leq_t2 = HOLogic.Not $ t1_leq_t2 |
378 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
378 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
379 val subgoal1 = (HOLogic.mk_Trueprop t1_leq_t2) :: terms2 @ [not_false] |
379 val subgoal1 = (HOLogic.mk_Trueprop t1_leq_t2) :: terms2 @ [not_false] |
380 val subgoal2 = (HOLogic.mk_Trueprop not_t1_leq_t2) :: terms1 @ [not_false] |
380 val subgoal2 = (HOLogic.mk_Trueprop not_t1_leq_t2) :: terms1 @ [not_false] |
385 | (Const (@{const_name Orderings.min}, _), [t1, t2]) => |
385 | (Const (@{const_name Orderings.min}, _), [t1, t2]) => |
386 let |
386 let |
387 val rev_terms = rev terms |
387 val rev_terms = rev terms |
388 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
388 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
389 val terms2 = map (subst_term [(split_term, t2)]) rev_terms |
389 val terms2 = map (subst_term [(split_term, t2)]) rev_terms |
390 val t1_leq_t2 = Const (@{const_name HOL.less_eq}, |
390 val t1_leq_t2 = Const (@{const_name Algebras.less_eq}, |
391 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
391 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
392 val not_t1_leq_t2 = HOLogic.Not $ t1_leq_t2 |
392 val not_t1_leq_t2 = HOLogic.Not $ t1_leq_t2 |
393 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
393 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
394 val subgoal1 = (HOLogic.mk_Trueprop t1_leq_t2) :: terms1 @ [not_false] |
394 val subgoal1 = (HOLogic.mk_Trueprop t1_leq_t2) :: terms1 @ [not_false] |
395 val subgoal2 = (HOLogic.mk_Trueprop not_t1_leq_t2) :: terms2 @ [not_false] |
395 val subgoal2 = (HOLogic.mk_Trueprop not_t1_leq_t2) :: terms2 @ [not_false] |
396 in |
396 in |
397 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
397 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
398 end |
398 end |
399 (* ?P (abs ?a) = ((0 <= ?a --> ?P ?a) & (?a < 0 --> ?P (- ?a))) *) |
399 (* ?P (abs ?a) = ((0 <= ?a --> ?P ?a) & (?a < 0 --> ?P (- ?a))) *) |
400 | (Const (@{const_name HOL.abs}, _), [t1]) => |
400 | (Const (@{const_name Algebras.abs}, _), [t1]) => |
401 let |
401 let |
402 val rev_terms = rev terms |
402 val rev_terms = rev terms |
403 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
403 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
404 val terms2 = map (subst_term [(split_term, Const (@{const_name HOL.uminus}, |
404 val terms2 = map (subst_term [(split_term, Const (@{const_name Algebras.uminus}, |
405 split_type --> split_type) $ t1)]) rev_terms |
405 split_type --> split_type) $ t1)]) rev_terms |
406 val zero = Const (@{const_name HOL.zero}, split_type) |
406 val zero = Const (@{const_name Algebras.zero}, split_type) |
407 val zero_leq_t1 = Const (@{const_name HOL.less_eq}, |
407 val zero_leq_t1 = Const (@{const_name Algebras.less_eq}, |
408 split_type --> split_type --> HOLogic.boolT) $ zero $ t1 |
408 split_type --> split_type --> HOLogic.boolT) $ zero $ t1 |
409 val t1_lt_zero = Const (@{const_name HOL.less}, |
409 val t1_lt_zero = Const (@{const_name Algebras.less}, |
410 split_type --> split_type --> HOLogic.boolT) $ t1 $ zero |
410 split_type --> split_type --> HOLogic.boolT) $ t1 $ zero |
411 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
411 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
412 val subgoal1 = (HOLogic.mk_Trueprop zero_leq_t1) :: terms1 @ [not_false] |
412 val subgoal1 = (HOLogic.mk_Trueprop zero_leq_t1) :: terms1 @ [not_false] |
413 val subgoal2 = (HOLogic.mk_Trueprop t1_lt_zero) :: terms2 @ [not_false] |
413 val subgoal2 = (HOLogic.mk_Trueprop t1_lt_zero) :: terms2 @ [not_false] |
414 in |
414 in |
415 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
415 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
416 end |
416 end |
417 (* ?P (?a - ?b) = ((?a < ?b --> ?P 0) & (ALL d. ?a = ?b + d --> ?P d)) *) |
417 (* ?P (?a - ?b) = ((?a < ?b --> ?P 0) & (ALL d. ?a = ?b + d --> ?P d)) *) |
418 | (Const (@{const_name HOL.minus}, _), [t1, t2]) => |
418 | (Const (@{const_name Algebras.minus}, _), [t1, t2]) => |
419 let |
419 let |
420 (* "d" in the above theorem becomes a new bound variable after NNF *) |
420 (* "d" in the above theorem becomes a new bound variable after NNF *) |
421 (* transformation, therefore some adjustment of indices is necessary *) |
421 (* transformation, therefore some adjustment of indices is necessary *) |
422 val rev_terms = rev terms |
422 val rev_terms = rev terms |
423 val zero = Const (@{const_name HOL.zero}, split_type) |
423 val zero = Const (@{const_name Algebras.zero}, split_type) |
424 val d = Bound 0 |
424 val d = Bound 0 |
425 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
425 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
426 val terms2 = map (subst_term [(incr_boundvars 1 split_term, d)]) |
426 val terms2 = map (subst_term [(incr_boundvars 1 split_term, d)]) |
427 (map (incr_boundvars 1) rev_terms) |
427 (map (incr_boundvars 1) rev_terms) |
428 val t1' = incr_boundvars 1 t1 |
428 val t1' = incr_boundvars 1 t1 |
429 val t2' = incr_boundvars 1 t2 |
429 val t2' = incr_boundvars 1 t2 |
430 val t1_lt_t2 = Const (@{const_name HOL.less}, |
430 val t1_lt_t2 = Const (@{const_name Algebras.less}, |
431 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
431 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
432 val t1_eq_t2_plus_d = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
432 val t1_eq_t2_plus_d = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
433 (Const (@{const_name HOL.plus}, |
433 (Const (@{const_name Algebras.plus}, |
434 split_type --> split_type --> split_type) $ t2' $ d) |
434 split_type --> split_type --> split_type) $ t2' $ d) |
435 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
435 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
436 val subgoal1 = (HOLogic.mk_Trueprop t1_lt_t2) :: terms1 @ [not_false] |
436 val subgoal1 = (HOLogic.mk_Trueprop t1_lt_t2) :: terms1 @ [not_false] |
437 val subgoal2 = (HOLogic.mk_Trueprop t1_eq_t2_plus_d) :: terms2 @ [not_false] |
437 val subgoal2 = (HOLogic.mk_Trueprop t1_eq_t2_plus_d) :: terms2 @ [not_false] |
438 in |
438 in |
440 end |
440 end |
441 (* ?P (nat ?i) = ((ALL n. ?i = of_nat n --> ?P n) & (?i < 0 --> ?P 0)) *) |
441 (* ?P (nat ?i) = ((ALL n. ?i = of_nat n --> ?P n) & (?i < 0 --> ?P 0)) *) |
442 | (Const ("Int.nat", _), [t1]) => |
442 | (Const ("Int.nat", _), [t1]) => |
443 let |
443 let |
444 val rev_terms = rev terms |
444 val rev_terms = rev terms |
445 val zero_int = Const (@{const_name HOL.zero}, HOLogic.intT) |
445 val zero_int = Const (@{const_name Algebras.zero}, HOLogic.intT) |
446 val zero_nat = Const (@{const_name HOL.zero}, HOLogic.natT) |
446 val zero_nat = Const (@{const_name Algebras.zero}, HOLogic.natT) |
447 val n = Bound 0 |
447 val n = Bound 0 |
448 val terms1 = map (subst_term [(incr_boundvars 1 split_term, n)]) |
448 val terms1 = map (subst_term [(incr_boundvars 1 split_term, n)]) |
449 (map (incr_boundvars 1) rev_terms) |
449 (map (incr_boundvars 1) rev_terms) |
450 val terms2 = map (subst_term [(split_term, zero_nat)]) rev_terms |
450 val terms2 = map (subst_term [(split_term, zero_nat)]) rev_terms |
451 val t1' = incr_boundvars 1 t1 |
451 val t1' = incr_boundvars 1 t1 |
452 val t1_eq_nat_n = Const ("op =", HOLogic.intT --> HOLogic.intT --> HOLogic.boolT) $ t1' $ |
452 val t1_eq_nat_n = Const ("op =", HOLogic.intT --> HOLogic.intT --> HOLogic.boolT) $ t1' $ |
453 (Const (@{const_name of_nat}, HOLogic.natT --> HOLogic.intT) $ n) |
453 (Const (@{const_name of_nat}, HOLogic.natT --> HOLogic.intT) $ n) |
454 val t1_lt_zero = Const (@{const_name HOL.less}, |
454 val t1_lt_zero = Const (@{const_name Algebras.less}, |
455 HOLogic.intT --> HOLogic.intT --> HOLogic.boolT) $ t1 $ zero_int |
455 HOLogic.intT --> HOLogic.intT --> HOLogic.boolT) $ t1 $ zero_int |
456 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
456 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
457 val subgoal1 = (HOLogic.mk_Trueprop t1_eq_nat_n) :: terms1 @ [not_false] |
457 val subgoal1 = (HOLogic.mk_Trueprop t1_eq_nat_n) :: terms1 @ [not_false] |
458 val subgoal2 = (HOLogic.mk_Trueprop t1_lt_zero) :: terms2 @ [not_false] |
458 val subgoal2 = (HOLogic.mk_Trueprop t1_lt_zero) :: terms2 @ [not_false] |
459 in |
459 in |
463 ((number_of ?k = 0 --> ?P ?n) & (~ (number_of ?k = 0) --> |
463 ((number_of ?k = 0 --> ?P ?n) & (~ (number_of ?k = 0) --> |
464 (ALL i j. j < number_of ?k --> ?n = number_of ?k * i + j --> ?P j))) *) |
464 (ALL i j. j < number_of ?k --> ?n = number_of ?k * i + j --> ?P j))) *) |
465 | (Const ("Divides.div_class.mod", Type ("fun", [Type ("nat", []), _])), [t1, t2]) => |
465 | (Const ("Divides.div_class.mod", Type ("fun", [Type ("nat", []), _])), [t1, t2]) => |
466 let |
466 let |
467 val rev_terms = rev terms |
467 val rev_terms = rev terms |
468 val zero = Const (@{const_name HOL.zero}, split_type) |
468 val zero = Const (@{const_name Algebras.zero}, split_type) |
469 val i = Bound 1 |
469 val i = Bound 1 |
470 val j = Bound 0 |
470 val j = Bound 0 |
471 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
471 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
472 val terms2 = map (subst_term [(incr_boundvars 2 split_term, j)]) |
472 val terms2 = map (subst_term [(incr_boundvars 2 split_term, j)]) |
473 (map (incr_boundvars 2) rev_terms) |
473 (map (incr_boundvars 2) rev_terms) |
475 val t2' = incr_boundvars 2 t2 |
475 val t2' = incr_boundvars 2 t2 |
476 val t2_eq_zero = Const ("op =", |
476 val t2_eq_zero = Const ("op =", |
477 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
477 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
478 val t2_neq_zero = HOLogic.mk_not (Const ("op =", |
478 val t2_neq_zero = HOLogic.mk_not (Const ("op =", |
479 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero) |
479 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero) |
480 val j_lt_t2 = Const (@{const_name HOL.less}, |
480 val j_lt_t2 = Const (@{const_name Algebras.less}, |
481 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
481 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
482 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
482 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
483 (Const (@{const_name HOL.plus}, split_type --> split_type --> split_type) $ |
483 (Const (@{const_name Algebras.plus}, split_type --> split_type --> split_type) $ |
484 (Const (@{const_name HOL.times}, |
484 (Const (@{const_name Algebras.times}, |
485 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
485 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
486 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
486 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
487 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
487 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
488 val subgoal2 = (map HOLogic.mk_Trueprop |
488 val subgoal2 = (map HOLogic.mk_Trueprop |
489 [t2_neq_zero, j_lt_t2, t1_eq_t2_times_i_plus_j]) |
489 [t2_neq_zero, j_lt_t2, t1_eq_t2_times_i_plus_j]) |
495 ((number_of ?k = 0 --> ?P 0) & (~ (number_of ?k = 0) --> |
495 ((number_of ?k = 0 --> ?P 0) & (~ (number_of ?k = 0) --> |
496 (ALL i j. j < number_of ?k --> ?n = number_of ?k * i + j --> ?P i))) *) |
496 (ALL i j. j < number_of ?k --> ?n = number_of ?k * i + j --> ?P i))) *) |
497 | (Const ("Divides.div_class.div", Type ("fun", [Type ("nat", []), _])), [t1, t2]) => |
497 | (Const ("Divides.div_class.div", Type ("fun", [Type ("nat", []), _])), [t1, t2]) => |
498 let |
498 let |
499 val rev_terms = rev terms |
499 val rev_terms = rev terms |
500 val zero = Const (@{const_name HOL.zero}, split_type) |
500 val zero = Const (@{const_name Algebras.zero}, split_type) |
501 val i = Bound 1 |
501 val i = Bound 1 |
502 val j = Bound 0 |
502 val j = Bound 0 |
503 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
503 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
504 val terms2 = map (subst_term [(incr_boundvars 2 split_term, i)]) |
504 val terms2 = map (subst_term [(incr_boundvars 2 split_term, i)]) |
505 (map (incr_boundvars 2) rev_terms) |
505 (map (incr_boundvars 2) rev_terms) |
507 val t2' = incr_boundvars 2 t2 |
507 val t2' = incr_boundvars 2 t2 |
508 val t2_eq_zero = Const ("op =", |
508 val t2_eq_zero = Const ("op =", |
509 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
509 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
510 val t2_neq_zero = HOLogic.mk_not (Const ("op =", |
510 val t2_neq_zero = HOLogic.mk_not (Const ("op =", |
511 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero) |
511 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero) |
512 val j_lt_t2 = Const (@{const_name HOL.less}, |
512 val j_lt_t2 = Const (@{const_name Algebras.less}, |
513 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
513 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
514 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
514 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
515 (Const (@{const_name HOL.plus}, split_type --> split_type --> split_type) $ |
515 (Const (@{const_name Algebras.plus}, split_type --> split_type --> split_type) $ |
516 (Const (@{const_name HOL.times}, |
516 (Const (@{const_name Algebras.times}, |
517 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
517 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
518 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
518 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
519 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
519 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
520 val subgoal2 = (map HOLogic.mk_Trueprop |
520 val subgoal2 = (map HOLogic.mk_Trueprop |
521 [t2_neq_zero, j_lt_t2, t1_eq_t2_times_i_plus_j]) |
521 [t2_neq_zero, j_lt_t2, t1_eq_t2_times_i_plus_j]) |
533 number_of ?k < j & j <= 0 & ?n = number_of ?k * i + j --> ?P j))) *) |
533 number_of ?k < j & j <= 0 & ?n = number_of ?k * i + j --> ?P j))) *) |
534 | (Const ("Divides.div_class.mod", |
534 | (Const ("Divides.div_class.mod", |
535 Type ("fun", [Type ("Int.int", []), _])), [t1, t2]) => |
535 Type ("fun", [Type ("Int.int", []), _])), [t1, t2]) => |
536 let |
536 let |
537 val rev_terms = rev terms |
537 val rev_terms = rev terms |
538 val zero = Const (@{const_name HOL.zero}, split_type) |
538 val zero = Const (@{const_name Algebras.zero}, split_type) |
539 val i = Bound 1 |
539 val i = Bound 1 |
540 val j = Bound 0 |
540 val j = Bound 0 |
541 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
541 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
542 val terms2_3 = map (subst_term [(incr_boundvars 2 split_term, j)]) |
542 val terms2_3 = map (subst_term [(incr_boundvars 2 split_term, j)]) |
543 (map (incr_boundvars 2) rev_terms) |
543 (map (incr_boundvars 2) rev_terms) |
544 val t1' = incr_boundvars 2 t1 |
544 val t1' = incr_boundvars 2 t1 |
545 val t2' = incr_boundvars 2 t2 |
545 val t2' = incr_boundvars 2 t2 |
546 val t2_eq_zero = Const ("op =", |
546 val t2_eq_zero = Const ("op =", |
547 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
547 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
548 val zero_lt_t2 = Const (@{const_name HOL.less}, |
548 val zero_lt_t2 = Const (@{const_name Algebras.less}, |
549 split_type --> split_type --> HOLogic.boolT) $ zero $ t2' |
549 split_type --> split_type --> HOLogic.boolT) $ zero $ t2' |
550 val t2_lt_zero = Const (@{const_name HOL.less}, |
550 val t2_lt_zero = Const (@{const_name Algebras.less}, |
551 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero |
551 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero |
552 val zero_leq_j = Const (@{const_name HOL.less_eq}, |
552 val zero_leq_j = Const (@{const_name Algebras.less_eq}, |
553 split_type --> split_type --> HOLogic.boolT) $ zero $ j |
553 split_type --> split_type --> HOLogic.boolT) $ zero $ j |
554 val j_leq_zero = Const (@{const_name HOL.less_eq}, |
554 val j_leq_zero = Const (@{const_name Algebras.less_eq}, |
555 split_type --> split_type --> HOLogic.boolT) $ j $ zero |
555 split_type --> split_type --> HOLogic.boolT) $ j $ zero |
556 val j_lt_t2 = Const (@{const_name HOL.less}, |
556 val j_lt_t2 = Const (@{const_name Algebras.less}, |
557 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
557 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
558 val t2_lt_j = Const (@{const_name HOL.less}, |
558 val t2_lt_j = Const (@{const_name Algebras.less}, |
559 split_type --> split_type--> HOLogic.boolT) $ t2' $ j |
559 split_type --> split_type--> HOLogic.boolT) $ t2' $ j |
560 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
560 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
561 (Const (@{const_name HOL.plus}, split_type --> split_type --> split_type) $ |
561 (Const (@{const_name Algebras.plus}, split_type --> split_type --> split_type) $ |
562 (Const (@{const_name HOL.times}, |
562 (Const (@{const_name Algebras.times}, |
563 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
563 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
564 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
564 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
565 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
565 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
566 val subgoal2 = (map HOLogic.mk_Trueprop [zero_lt_t2, zero_leq_j]) |
566 val subgoal2 = (map HOLogic.mk_Trueprop [zero_lt_t2, zero_leq_j]) |
567 @ hd terms2_3 |
567 @ hd terms2_3 |
587 number_of ?k < j & j <= 0 & ?n = number_of ?k * i + j --> ?P i))) *) |
587 number_of ?k < j & j <= 0 & ?n = number_of ?k * i + j --> ?P i))) *) |
588 | (Const ("Divides.div_class.div", |
588 | (Const ("Divides.div_class.div", |
589 Type ("fun", [Type ("Int.int", []), _])), [t1, t2]) => |
589 Type ("fun", [Type ("Int.int", []), _])), [t1, t2]) => |
590 let |
590 let |
591 val rev_terms = rev terms |
591 val rev_terms = rev terms |
592 val zero = Const (@{const_name HOL.zero}, split_type) |
592 val zero = Const (@{const_name Algebras.zero}, split_type) |
593 val i = Bound 1 |
593 val i = Bound 1 |
594 val j = Bound 0 |
594 val j = Bound 0 |
595 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
595 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
596 val terms2_3 = map (subst_term [(incr_boundvars 2 split_term, i)]) |
596 val terms2_3 = map (subst_term [(incr_boundvars 2 split_term, i)]) |
597 (map (incr_boundvars 2) rev_terms) |
597 (map (incr_boundvars 2) rev_terms) |
598 val t1' = incr_boundvars 2 t1 |
598 val t1' = incr_boundvars 2 t1 |
599 val t2' = incr_boundvars 2 t2 |
599 val t2' = incr_boundvars 2 t2 |
600 val t2_eq_zero = Const ("op =", |
600 val t2_eq_zero = Const ("op =", |
601 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
601 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
602 val zero_lt_t2 = Const (@{const_name HOL.less}, |
602 val zero_lt_t2 = Const (@{const_name Algebras.less}, |
603 split_type --> split_type --> HOLogic.boolT) $ zero $ t2' |
603 split_type --> split_type --> HOLogic.boolT) $ zero $ t2' |
604 val t2_lt_zero = Const (@{const_name HOL.less}, |
604 val t2_lt_zero = Const (@{const_name Algebras.less}, |
605 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero |
605 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero |
606 val zero_leq_j = Const (@{const_name HOL.less_eq}, |
606 val zero_leq_j = Const (@{const_name Algebras.less_eq}, |
607 split_type --> split_type --> HOLogic.boolT) $ zero $ j |
607 split_type --> split_type --> HOLogic.boolT) $ zero $ j |
608 val j_leq_zero = Const (@{const_name HOL.less_eq}, |
608 val j_leq_zero = Const (@{const_name Algebras.less_eq}, |
609 split_type --> split_type --> HOLogic.boolT) $ j $ zero |
609 split_type --> split_type --> HOLogic.boolT) $ j $ zero |
610 val j_lt_t2 = Const (@{const_name HOL.less}, |
610 val j_lt_t2 = Const (@{const_name Algebras.less}, |
611 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
611 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
612 val t2_lt_j = Const (@{const_name HOL.less}, |
612 val t2_lt_j = Const (@{const_name Algebras.less}, |
613 split_type --> split_type--> HOLogic.boolT) $ t2' $ j |
613 split_type --> split_type--> HOLogic.boolT) $ t2' $ j |
614 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
614 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
615 (Const (@{const_name HOL.plus}, split_type --> split_type --> split_type) $ |
615 (Const (@{const_name Algebras.plus}, split_type --> split_type --> split_type) $ |
616 (Const (@{const_name HOL.times}, |
616 (Const (@{const_name Algebras.times}, |
617 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
617 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
618 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
618 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
619 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
619 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
620 val subgoal2 = (map HOLogic.mk_Trueprop [zero_lt_t2, zero_leq_j]) |
620 val subgoal2 = (map HOLogic.mk_Trueprop [zero_lt_t2, zero_leq_j]) |
621 @ hd terms2_3 |
621 @ hd terms2_3 |