281 (* decompose nested multiplications, bracketing them to the right and combining |
281 (* decompose nested multiplications, bracketing them to the right and combining |
282 all their coefficients |
282 all their coefficients |
283 *) |
283 *) |
284 fun demult (inj_consts : (string * typ) list) : term * Rat.rat -> term option * Rat.rat = |
284 fun demult (inj_consts : (string * typ) list) : term * Rat.rat -> term option * Rat.rat = |
285 let |
285 let |
286 fun demult ((mC as Const ("HOL.times", _)) $ s $ t, m) = ( |
286 fun demult ((mC as Const (@{const_name HOL.times}, _)) $ s $ t, m) = ( |
287 (case s of |
287 (case s of |
288 Const ("Numeral.number_of", _) $ n => |
288 Const ("Numeral.number_class.number_of", _) $ n => |
289 demult (t, Rat.mult m (Rat.rat_of_int (HOLogic.dest_numeral n))) |
289 demult (t, Rat.mult m (Rat.rat_of_int (HOLogic.dest_numeral n))) |
290 | Const ("HOL.uminus", _) $ (Const ("Numeral.number_of", _) $ n) => |
290 | Const (@{const_name HOL.uminus}, _) $ (Const ("Numeral.number_class.number_of", _) $ n) => |
291 demult (t, Rat.mult m (Rat.rat_of_int (~(HOLogic.dest_numeral n)))) |
291 demult (t, Rat.mult m (Rat.rat_of_int (~(HOLogic.dest_numeral n)))) |
292 | Const ("Suc", _) $ _ => |
292 | Const (@{const_name Suc}, _) $ _ => |
293 demult (t, Rat.mult m (Rat.rat_of_int (HOLogic.dest_nat s))) |
293 demult (t, Rat.mult m (Rat.rat_of_int (HOLogic.dest_nat s))) |
294 | Const ("HOL.times", _) $ s1 $ s2 => |
294 | Const (@{const_name HOL.times}, _) $ s1 $ s2 => |
295 demult (mC $ s1 $ (mC $ s2 $ t), m) |
295 demult (mC $ s1 $ (mC $ s2 $ t), m) |
296 | Const ("HOL.divide", _) $ numt $ (Const ("Numeral.number_of", _) $ dent) => |
296 | Const (@{const_name HOL.divide}, _) $ numt $ (Const ("Numeral.number_class.number_of", _) $ dent) => |
297 let |
297 let |
298 val den = HOLogic.dest_numeral dent |
298 val den = HOLogic.dest_numeral dent |
299 in |
299 in |
300 if den = 0 then |
300 if den = 0 then |
301 raise Zero |
301 raise Zero |
304 end |
304 end |
305 | _ => |
305 | _ => |
306 atomult (mC, s, t, m) |
306 atomult (mC, s, t, m) |
307 ) handle TERM _ => atomult (mC, s, t, m) |
307 ) handle TERM _ => atomult (mC, s, t, m) |
308 ) |
308 ) |
309 | demult (atom as Const("HOL.divide", _) $ t $ (Const ("Numeral.number_of", _) $ dent), m) = |
309 | demult (atom as Const(@{const_name HOL.divide}, _) $ t $ (Const ("Numeral.number_class.number_of", _) $ dent), m) = |
310 (let |
310 (let |
311 val den = HOLogic.dest_numeral dent |
311 val den = HOLogic.dest_numeral dent |
312 in |
312 in |
313 if den = 0 then |
313 if den = 0 then |
314 raise Zero |
314 raise Zero |
315 else |
315 else |
316 demult (t, Rat.mult m (Rat.inv (Rat.rat_of_int den))) |
316 demult (t, Rat.mult m (Rat.inv (Rat.rat_of_int den))) |
317 end |
317 end |
318 handle TERM _ => (SOME atom, m)) |
318 handle TERM _ => (SOME atom, m)) |
319 | demult (Const ("HOL.zero", _), m) = (NONE, Rat.zero) |
319 | demult (Const (@{const_name HOL.zero}, _), m) = (NONE, Rat.zero) |
320 | demult (Const ("HOL.one", _), m) = (NONE, m) |
320 | demult (Const (@{const_name HOL.one}, _), m) = (NONE, m) |
321 | demult (t as Const ("Numeral.number_of", _) $ n, m) = |
321 | demult (t as Const ("Numeral.number_class.number_of", _) $ n, m) = |
322 ((NONE, Rat.mult m (Rat.rat_of_int (HOLogic.dest_numeral n))) |
322 ((NONE, Rat.mult m (Rat.rat_of_int (HOLogic.dest_numeral n))) |
323 handle TERM _ => (SOME t, m)) |
323 handle TERM _ => (SOME t, m)) |
324 | demult (Const ("HOL.uminus", _) $ t, m) = demult (t, Rat.neg m) |
324 | demult (Const (@{const_name HOL.uminus}, _) $ t, m) = demult (t, Rat.neg m) |
325 | demult (t as Const f $ x, m) = |
325 | demult (t as Const f $ x, m) = |
326 (if f mem inj_consts then SOME x else SOME t, m) |
326 (if member (op =) inj_consts f then SOME x else SOME t, m) |
327 | demult (atom, m) = (SOME atom, m) |
327 | demult (atom, m) = (SOME atom, m) |
328 and |
328 and |
329 atomult (mC, atom, t, m) = ( |
329 atomult (mC, atom, t, m) = ( |
330 case demult (t, m) of (NONE, m') => (SOME atom, m') |
330 case demult (t, m) of (NONE, m') => (SOME atom, m') |
331 | (SOME t', m') => (SOME (mC $ atom $ t'), m') |
331 | (SOME t', m') => (SOME (mC $ atom $ t'), m') |
334 |
334 |
335 fun decomp0 (inj_consts : (string * typ) list) (rel : string, lhs : term, rhs : term) : |
335 fun decomp0 (inj_consts : (string * typ) list) (rel : string, lhs : term, rhs : term) : |
336 ((term * Rat.rat) list * Rat.rat * string * (term * Rat.rat) list * Rat.rat) option = |
336 ((term * Rat.rat) list * Rat.rat * string * (term * Rat.rat) list * Rat.rat) option = |
337 let |
337 let |
338 (* Turn term into list of summand * multiplicity plus a constant *) |
338 (* Turn term into list of summand * multiplicity plus a constant *) |
339 fun poly (Const ("HOL.plus", _) $ s $ t, m : Rat.rat, pi : (term * Rat.rat) list * Rat.rat) = |
339 fun poly (Const (@{const_name HOL.plus}, _) $ s $ t, m : Rat.rat, pi : (term * Rat.rat) list * Rat.rat) = |
340 poly (s, m, poly (t, m, pi)) |
340 poly (s, m, poly (t, m, pi)) |
341 | poly (all as Const ("HOL.minus", T) $ s $ t, m, pi) = |
341 | poly (all as Const (@{const_name HOL.minus}, T) $ s $ t, m, pi) = |
342 if nT T then add_atom all m pi else poly (s, m, poly (t, Rat.neg m, pi)) |
342 if nT T then add_atom all m pi else poly (s, m, poly (t, Rat.neg m, pi)) |
343 | poly (all as Const ("HOL.uminus", T) $ t, m, pi) = |
343 | poly (all as Const (@{const_name HOL.uminus}, T) $ t, m, pi) = |
344 if nT T then add_atom all m pi else poly (t, Rat.neg m, pi) |
344 if nT T then add_atom all m pi else poly (t, Rat.neg m, pi) |
345 | poly (Const ("HOL.zero", _), _, pi) = |
345 | poly (Const (@{const_name HOL.zero}, _), _, pi) = |
346 pi |
346 pi |
347 | poly (Const ("HOL.one", _), m, (p, i)) = |
347 | poly (Const (@{const_name HOL.one}, _), m, (p, i)) = |
348 (p, Rat.add i m) |
348 (p, Rat.add i m) |
349 | poly (Const ("Suc", _) $ t, m, (p, i)) = |
349 | poly (Const (@{const_name Suc}, _) $ t, m, (p, i)) = |
350 poly (t, m, (p, Rat.add i m)) |
350 poly (t, m, (p, Rat.add i m)) |
351 | poly (all as Const ("HOL.times", _) $ _ $ _, m, pi as (p, i)) = |
351 | poly (all as Const (@{const_name HOL.times}, _) $ _ $ _, m, pi as (p, i)) = |
352 (case demult inj_consts (all, m) of |
352 (case demult inj_consts (all, m) of |
353 (NONE, m') => (p, Rat.add i m') |
353 (NONE, m') => (p, Rat.add i m') |
354 | (SOME u, m') => add_atom u m' pi) |
354 | (SOME u, m') => add_atom u m' pi) |
355 | poly (all as Const ("HOL.divide", _) $ _ $ _, m, pi as (p, i)) = |
355 | poly (all as Const (@{const_name HOL.divide}, _) $ _ $ _, m, pi as (p, i)) = |
356 (case demult inj_consts (all, m) of |
356 (case demult inj_consts (all, m) of |
357 (NONE, m') => (p, Rat.add i m') |
357 (NONE, m') => (p, Rat.add i m') |
358 | (SOME u, m') => add_atom u m' pi) |
358 | (SOME u, m') => add_atom u m' pi) |
359 | poly (all as Const ("Numeral.number_of", Type(_,[_,T])) $ t, m, pi as (p, i)) = |
359 | poly (all as Const ("Numeral.number_class.number_of", Type(_,[_,T])) $ t, m, pi as (p, i)) = |
360 (let val k = HOLogic.dest_numeral t |
360 (let val k = HOLogic.dest_numeral t |
361 val k2 = if k < 0 andalso T = HOLogic.natT then 0 else k |
361 val k2 = if k < 0 andalso T = HOLogic.natT then 0 else k |
362 in (p, Rat.add i (Rat.mult m (Rat.rat_of_int k2))) end |
362 in (p, Rat.add i (Rat.mult m (Rat.rat_of_int k2))) end |
363 handle TERM _ => add_atom all m pi) |
363 handle TERM _ => add_atom all m pi) |
364 | poly (all as Const f $ x, m, pi) = |
364 | poly (all as Const f $ x, m, pi) = |
513 NONE |
513 NONE |
514 | ((_, _, _, split_type, split_term) :: _) => ( |
514 | ((_, _, _, split_type, split_term) :: _) => ( |
515 (* ignore all but the first possible split *) |
515 (* ignore all but the first possible split *) |
516 case strip_comb split_term of |
516 case strip_comb split_term of |
517 (* ?P (max ?i ?j) = ((?i <= ?j --> ?P ?j) & (~ ?i <= ?j --> ?P ?i)) *) |
517 (* ?P (max ?i ?j) = ((?i <= ?j --> ?P ?j) & (~ ?i <= ?j --> ?P ?i)) *) |
518 (Const ("Orderings.max", _), [t1, t2]) => |
518 (Const (@{const_name Orderings.max}, _), [t1, t2]) => |
519 let |
519 let |
520 val rev_terms = rev terms |
520 val rev_terms = rev terms |
521 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
521 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
522 val terms2 = map (subst_term [(split_term, t2)]) rev_terms |
522 val terms2 = map (subst_term [(split_term, t2)]) rev_terms |
523 val t1_leq_t2 = Const ("Orderings.less_eq", |
523 val t1_leq_t2 = Const (@{const_name Orderings.less_eq}, |
524 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
524 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
525 val not_t1_leq_t2 = HOLogic.Not $ t1_leq_t2 |
525 val not_t1_leq_t2 = HOLogic.Not $ t1_leq_t2 |
526 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
526 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
527 val subgoal1 = (HOLogic.mk_Trueprop t1_leq_t2) :: terms2 @ [not_false] |
527 val subgoal1 = (HOLogic.mk_Trueprop t1_leq_t2) :: terms2 @ [not_false] |
528 val subgoal2 = (HOLogic.mk_Trueprop not_t1_leq_t2) :: terms1 @ [not_false] |
528 val subgoal2 = (HOLogic.mk_Trueprop not_t1_leq_t2) :: terms1 @ [not_false] |
529 in |
529 in |
530 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
530 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
531 end |
531 end |
532 (* ?P (min ?i ?j) = ((?i <= ?j --> ?P ?i) & (~ ?i <= ?j --> ?P ?j)) *) |
532 (* ?P (min ?i ?j) = ((?i <= ?j --> ?P ?i) & (~ ?i <= ?j --> ?P ?j)) *) |
533 | (Const ("Orderings.min", _), [t1, t2]) => |
533 | (Const (@{const_name Orderings.min}, _), [t1, t2]) => |
534 let |
534 let |
535 val rev_terms = rev terms |
535 val rev_terms = rev terms |
536 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
536 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
537 val terms2 = map (subst_term [(split_term, t2)]) rev_terms |
537 val terms2 = map (subst_term [(split_term, t2)]) rev_terms |
538 val t1_leq_t2 = Const ("Orderings.less_eq", |
538 val t1_leq_t2 = Const (@{const_name Orderings.less_eq}, |
539 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
539 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
540 val not_t1_leq_t2 = HOLogic.Not $ t1_leq_t2 |
540 val not_t1_leq_t2 = HOLogic.Not $ t1_leq_t2 |
541 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
541 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
542 val subgoal1 = (HOLogic.mk_Trueprop t1_leq_t2) :: terms1 @ [not_false] |
542 val subgoal1 = (HOLogic.mk_Trueprop t1_leq_t2) :: terms1 @ [not_false] |
543 val subgoal2 = (HOLogic.mk_Trueprop not_t1_leq_t2) :: terms2 @ [not_false] |
543 val subgoal2 = (HOLogic.mk_Trueprop not_t1_leq_t2) :: terms2 @ [not_false] |
544 in |
544 in |
545 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
545 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
546 end |
546 end |
547 (* ?P (abs ?a) = ((0 <= ?a --> ?P ?a) & (?a < 0 --> ?P (- ?a))) *) |
547 (* ?P (abs ?a) = ((0 <= ?a --> ?P ?a) & (?a < 0 --> ?P (- ?a))) *) |
548 | (Const ("HOL.abs", _), [t1]) => |
548 | (Const (@{const_name HOL.abs}, _), [t1]) => |
549 let |
549 let |
550 val rev_terms = rev terms |
550 val rev_terms = rev terms |
551 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
551 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
552 val terms2 = map (subst_term [(split_term, Const ("HOL.uminus", |
552 val terms2 = map (subst_term [(split_term, Const (@{const_name HOL.uminus}, |
553 split_type --> split_type) $ t1)]) rev_terms |
553 split_type --> split_type) $ t1)]) rev_terms |
554 val zero = Const ("HOL.zero", split_type) |
554 val zero = Const (@{const_name HOL.zero}, split_type) |
555 val zero_leq_t1 = Const ("Orderings.less_eq", |
555 val zero_leq_t1 = Const (@{const_name Orderings.less_eq}, |
556 split_type --> split_type --> HOLogic.boolT) $ zero $ t1 |
556 split_type --> split_type --> HOLogic.boolT) $ zero $ t1 |
557 val t1_lt_zero = Const ("Orderings.less", |
557 val t1_lt_zero = Const (@{const_name Orderings.less}, |
558 split_type --> split_type --> HOLogic.boolT) $ t1 $ zero |
558 split_type --> split_type --> HOLogic.boolT) $ t1 $ zero |
559 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
559 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
560 val subgoal1 = (HOLogic.mk_Trueprop zero_leq_t1) :: terms1 @ [not_false] |
560 val subgoal1 = (HOLogic.mk_Trueprop zero_leq_t1) :: terms1 @ [not_false] |
561 val subgoal2 = (HOLogic.mk_Trueprop t1_lt_zero) :: terms2 @ [not_false] |
561 val subgoal2 = (HOLogic.mk_Trueprop t1_lt_zero) :: terms2 @ [not_false] |
562 in |
562 in |
563 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
563 SOME [(Ts, subgoal1), (Ts, subgoal2)] |
564 end |
564 end |
565 (* ?P (?a - ?b) = ((?a < ?b --> ?P 0) & (ALL d. ?a = ?b + d --> ?P d)) *) |
565 (* ?P (?a - ?b) = ((?a < ?b --> ?P 0) & (ALL d. ?a = ?b + d --> ?P d)) *) |
566 | (Const ("HOL.minus", _), [t1, t2]) => |
566 | (Const (@{const_name HOL.minus}, _), [t1, t2]) => |
567 let |
567 let |
568 (* "d" in the above theorem becomes a new bound variable after NNF *) |
568 (* "d" in the above theorem becomes a new bound variable after NNF *) |
569 (* transformation, therefore some adjustment of indices is necessary *) |
569 (* transformation, therefore some adjustment of indices is necessary *) |
570 val rev_terms = rev terms |
570 val rev_terms = rev terms |
571 val zero = Const ("HOL.zero", split_type) |
571 val zero = Const (@{const_name HOL.zero}, split_type) |
572 val d = Bound 0 |
572 val d = Bound 0 |
573 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
573 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
574 val terms2 = map (subst_term [(incr_boundvars 1 split_term, d)]) |
574 val terms2 = map (subst_term [(incr_boundvars 1 split_term, d)]) |
575 (map (incr_boundvars 1) rev_terms) |
575 (map (incr_boundvars 1) rev_terms) |
576 val t1' = incr_boundvars 1 t1 |
576 val t1' = incr_boundvars 1 t1 |
577 val t2' = incr_boundvars 1 t2 |
577 val t2' = incr_boundvars 1 t2 |
578 val t1_lt_t2 = Const ("Orderings.less", |
578 val t1_lt_t2 = Const (@{const_name Orderings.less}, |
579 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
579 split_type --> split_type --> HOLogic.boolT) $ t1 $ t2 |
580 val t1_eq_t2_plus_d = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
580 val t1_eq_t2_plus_d = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
581 (Const ("HOL.plus", |
581 (Const (@{const_name HOL.plus}, |
582 split_type --> split_type --> split_type) $ t2' $ d) |
582 split_type --> split_type --> split_type) $ t2' $ d) |
583 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
583 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
584 val subgoal1 = (HOLogic.mk_Trueprop t1_lt_t2) :: terms1 @ [not_false] |
584 val subgoal1 = (HOLogic.mk_Trueprop t1_lt_t2) :: terms1 @ [not_false] |
585 val subgoal2 = (HOLogic.mk_Trueprop t1_eq_t2_plus_d) :: terms2 @ [not_false] |
585 val subgoal2 = (HOLogic.mk_Trueprop t1_eq_t2_plus_d) :: terms2 @ [not_false] |
586 in |
586 in |
588 end |
588 end |
589 (* ?P (nat ?i) = ((ALL n. ?i = int n --> ?P n) & (?i < 0 --> ?P 0)) *) |
589 (* ?P (nat ?i) = ((ALL n. ?i = int n --> ?P n) & (?i < 0 --> ?P 0)) *) |
590 | (Const ("IntDef.nat", _), [t1]) => |
590 | (Const ("IntDef.nat", _), [t1]) => |
591 let |
591 let |
592 val rev_terms = rev terms |
592 val rev_terms = rev terms |
593 val zero_int = Const ("HOL.zero", HOLogic.intT) |
593 val zero_int = Const (@{const_name HOL.zero}, HOLogic.intT) |
594 val zero_nat = Const ("HOL.zero", HOLogic.natT) |
594 val zero_nat = Const (@{const_name HOL.zero}, HOLogic.natT) |
595 val n = Bound 0 |
595 val n = Bound 0 |
596 val terms1 = map (subst_term [(incr_boundvars 1 split_term, n)]) |
596 val terms1 = map (subst_term [(incr_boundvars 1 split_term, n)]) |
597 (map (incr_boundvars 1) rev_terms) |
597 (map (incr_boundvars 1) rev_terms) |
598 val terms2 = map (subst_term [(split_term, zero_nat)]) rev_terms |
598 val terms2 = map (subst_term [(split_term, zero_nat)]) rev_terms |
599 val t1' = incr_boundvars 1 t1 |
599 val t1' = incr_boundvars 1 t1 |
600 val t1_eq_int_n = Const ("op =", HOLogic.intT --> HOLogic.intT --> HOLogic.boolT) $ t1' $ |
600 val t1_eq_int_n = Const ("op =", HOLogic.intT --> HOLogic.intT --> HOLogic.boolT) $ t1' $ |
601 (Const ("IntDef.int", HOLogic.natT --> HOLogic.intT) $ n) |
601 (Const ("IntDef.int", HOLogic.natT --> HOLogic.intT) $ n) |
602 val t1_lt_zero = Const ("Orderings.less", |
602 val t1_lt_zero = Const (@{const_name Orderings.less}, |
603 HOLogic.intT --> HOLogic.intT --> HOLogic.boolT) $ t1 $ zero_int |
603 HOLogic.intT --> HOLogic.intT --> HOLogic.boolT) $ t1 $ zero_int |
604 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
604 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
605 val subgoal1 = (HOLogic.mk_Trueprop t1_eq_int_n) :: terms1 @ [not_false] |
605 val subgoal1 = (HOLogic.mk_Trueprop t1_eq_int_n) :: terms1 @ [not_false] |
606 val subgoal2 = (HOLogic.mk_Trueprop t1_lt_zero) :: terms2 @ [not_false] |
606 val subgoal2 = (HOLogic.mk_Trueprop t1_lt_zero) :: terms2 @ [not_false] |
607 in |
607 in |
608 SOME [(HOLogic.natT :: Ts, subgoal1), (Ts, subgoal2)] |
608 SOME [(HOLogic.natT :: Ts, subgoal1), (Ts, subgoal2)] |
609 end |
609 end |
610 (* "?P ((?n::nat) mod (number_of ?k)) = |
610 (* "?P ((?n::nat) mod (number_of ?k)) = |
611 ((number_of ?k = 0 --> ?P ?n) & (~ (number_of ?k = 0) --> |
611 ((number_of ?k = 0 --> ?P ?n) & (~ (number_of ?k = 0) --> |
612 (ALL i j. j < number_of ?k --> ?n = number_of ?k * i + j --> ?P j))) *) |
612 (ALL i j. j < number_of ?k --> ?n = number_of ?k * i + j --> ?P j))) *) |
613 | (Const ("Divides.mod", Type ("fun", [Type ("nat", []), _])), [t1, t2]) => |
613 | (Const ("Divides.div_class.mod", Type ("fun", [Type ("nat", []), _])), [t1, t2]) => |
614 let |
614 let |
615 val rev_terms = rev terms |
615 val rev_terms = rev terms |
616 val zero = Const ("HOL.zero", split_type) |
616 val zero = Const (@{const_name HOL.zero}, split_type) |
617 val i = Bound 1 |
617 val i = Bound 1 |
618 val j = Bound 0 |
618 val j = Bound 0 |
619 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
619 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
620 val terms2 = map (subst_term [(incr_boundvars 2 split_term, j)]) |
620 val terms2 = map (subst_term [(incr_boundvars 2 split_term, j)]) |
621 (map (incr_boundvars 2) rev_terms) |
621 (map (incr_boundvars 2) rev_terms) |
623 val t2' = incr_boundvars 2 t2 |
623 val t2' = incr_boundvars 2 t2 |
624 val t2_eq_zero = Const ("op =", |
624 val t2_eq_zero = Const ("op =", |
625 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
625 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
626 val t2_neq_zero = HOLogic.mk_not (Const ("op =", |
626 val t2_neq_zero = HOLogic.mk_not (Const ("op =", |
627 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero) |
627 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero) |
628 val j_lt_t2 = Const ("Orderings.less", |
628 val j_lt_t2 = Const (@{const_name Orderings.less}, |
629 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
629 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
630 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
630 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
631 (Const ("HOL.plus", split_type --> split_type --> split_type) $ |
631 (Const (@{const_name HOL.plus}, split_type --> split_type --> split_type) $ |
632 (Const ("HOL.times", |
632 (Const (@{const_name HOL.times}, |
633 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
633 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
634 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
634 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
635 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
635 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
636 val subgoal2 = (map HOLogic.mk_Trueprop |
636 val subgoal2 = (map HOLogic.mk_Trueprop |
637 [t2_neq_zero, j_lt_t2, t1_eq_t2_times_i_plus_j]) |
637 [t2_neq_zero, j_lt_t2, t1_eq_t2_times_i_plus_j]) |
655 val t2' = incr_boundvars 2 t2 |
655 val t2' = incr_boundvars 2 t2 |
656 val t2_eq_zero = Const ("op =", |
656 val t2_eq_zero = Const ("op =", |
657 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
657 split_type --> split_type --> HOLogic.boolT) $ t2 $ zero |
658 val t2_neq_zero = HOLogic.mk_not (Const ("op =", |
658 val t2_neq_zero = HOLogic.mk_not (Const ("op =", |
659 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero) |
659 split_type --> split_type --> HOLogic.boolT) $ t2' $ zero) |
660 val j_lt_t2 = Const ("Orderings.less", |
660 val j_lt_t2 = Const (@{const_name Orderings.less}, |
661 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
661 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
662 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
662 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
663 (Const ("HOL.plus", split_type --> split_type --> split_type) $ |
663 (Const (@{const_name HOL.plus}, split_type --> split_type --> split_type) $ |
664 (Const ("HOL.times", |
664 (Const (@{const_name HOL.times}, |
665 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
665 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
666 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
666 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
667 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
667 val subgoal1 = (HOLogic.mk_Trueprop t2_eq_zero) :: terms1 @ [not_false] |
668 val subgoal2 = (map HOLogic.mk_Trueprop |
668 val subgoal2 = (map HOLogic.mk_Trueprop |
669 [t2_neq_zero, j_lt_t2, t1_eq_t2_times_i_plus_j]) |
669 [t2_neq_zero, j_lt_t2, t1_eq_t2_times_i_plus_j]) |
675 ((iszero (number_of ?k) --> ?P ?n) & |
675 ((iszero (number_of ?k) --> ?P ?n) & |
676 (neg (number_of (uminus ?k)) --> |
676 (neg (number_of (uminus ?k)) --> |
677 (ALL i j. 0 <= j & j < number_of ?k & ?n = number_of ?k * i + j --> ?P j)) & |
677 (ALL i j. 0 <= j & j < number_of ?k & ?n = number_of ?k * i + j --> ?P j)) & |
678 (neg (number_of ?k) --> |
678 (neg (number_of ?k) --> |
679 (ALL i j. number_of ?k < j & j <= 0 & ?n = number_of ?k * i + j --> ?P j))) *) |
679 (ALL i j. number_of ?k < j & j <= 0 & ?n = number_of ?k * i + j --> ?P j))) *) |
680 | (Const ("Divides.mod", |
680 | (Const ("Divides.div_class.mod", |
681 Type ("fun", [Type ("IntDef.int", []), _])), [t1, t2 as (number_of $ k)]) => |
681 Type ("fun", [Type ("IntDef.int", []), _])), [t1, t2 as (number_of $ k)]) => |
682 let |
682 let |
683 val rev_terms = rev terms |
683 val rev_terms = rev terms |
684 val zero = Const ("HOL.zero", split_type) |
684 val zero = Const (@{const_name HOL.zero}, split_type) |
685 val i = Bound 1 |
685 val i = Bound 1 |
686 val j = Bound 0 |
686 val j = Bound 0 |
687 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
687 val terms1 = map (subst_term [(split_term, t1)]) rev_terms |
688 val terms2_3 = map (subst_term [(incr_boundvars 2 split_term, j)]) |
688 val terms2_3 = map (subst_term [(incr_boundvars 2 split_term, j)]) |
689 (map (incr_boundvars 2) rev_terms) |
689 (map (incr_boundvars 2) rev_terms) |
690 val t1' = incr_boundvars 2 t1 |
690 val t1' = incr_boundvars 2 t1 |
691 val (t2' as (_ $ k')) = incr_boundvars 2 t2 |
691 val (t2' as (_ $ k')) = incr_boundvars 2 t2 |
692 val iszero_t2 = Const ("IntDef.iszero", split_type --> HOLogic.boolT) $ t2 |
692 val iszero_t2 = Const ("IntDef.iszero", split_type --> HOLogic.boolT) $ t2 |
693 val neg_minus_k = Const ("IntDef.neg", split_type --> HOLogic.boolT) $ |
693 val neg_minus_k = Const ("IntDef.neg", split_type --> HOLogic.boolT) $ |
694 (number_of $ |
694 (number_of $ |
695 (Const ("HOL.uminus", |
695 (Const (@{const_name HOL.uminus}, |
696 HOLogic.intT --> HOLogic.intT) $ k')) |
696 HOLogic.intT --> HOLogic.intT) $ k')) |
697 val zero_leq_j = Const ("Orderings.less_eq", |
697 val zero_leq_j = Const (@{const_name Orderings.less_eq}, |
698 split_type --> split_type --> HOLogic.boolT) $ zero $ j |
698 split_type --> split_type --> HOLogic.boolT) $ zero $ j |
699 val j_lt_t2 = Const ("Orderings.less", |
699 val j_lt_t2 = Const (@{const_name Orderings.less}, |
700 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
700 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
701 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
701 val t1_eq_t2_times_i_plus_j = Const ("op =", split_type --> split_type --> HOLogic.boolT) $ t1' $ |
702 (Const ("HOL.plus", split_type --> split_type --> split_type) $ |
702 (Const (@{const_name HOL.plus}, split_type --> split_type --> split_type) $ |
703 (Const ("HOL.times", |
703 (Const (@{const_name HOL.times}, |
704 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
704 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
705 val neg_t2 = Const ("IntDef.neg", split_type --> HOLogic.boolT) $ t2' |
705 val neg_t2 = Const ("IntDef.neg", split_type --> HOLogic.boolT) $ t2' |
706 val t2_lt_j = Const ("Orderings.less", |
706 val t2_lt_j = Const (@{const_name Orderings.less}, |
707 split_type --> split_type--> HOLogic.boolT) $ t2' $ j |
707 split_type --> split_type--> HOLogic.boolT) $ t2' $ j |
708 val j_leq_zero = Const ("Orderings.less_eq", |
708 val j_leq_zero = Const (@{const_name Orderings.less_eq}, |
709 split_type --> split_type --> HOLogic.boolT) $ j $ zero |
709 split_type --> split_type --> HOLogic.boolT) $ j $ zero |
710 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
710 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
711 val subgoal1 = (HOLogic.mk_Trueprop iszero_t2) :: terms1 @ [not_false] |
711 val subgoal1 = (HOLogic.mk_Trueprop iszero_t2) :: terms1 @ [not_false] |
712 val subgoal2 = (map HOLogic.mk_Trueprop [neg_minus_k, zero_leq_j]) |
712 val subgoal2 = (map HOLogic.mk_Trueprop [neg_minus_k, zero_leq_j]) |
713 @ hd terms2_3 |
713 @ hd terms2_3 |
727 ((iszero (number_of ?k) --> ?P 0) & |
727 ((iszero (number_of ?k) --> ?P 0) & |
728 (neg (number_of (uminus ?k)) --> |
728 (neg (number_of (uminus ?k)) --> |
729 (ALL i. (EX j. 0 <= j & j < number_of ?k & ?n = number_of ?k * i + j) --> ?P i)) & |
729 (ALL i. (EX j. 0 <= j & j < number_of ?k & ?n = number_of ?k * i + j) --> ?P i)) & |
730 (neg (number_of ?k) --> |
730 (neg (number_of ?k) --> |
731 (ALL i. (EX j. number_of ?k < j & j <= 0 & ?n = number_of ?k * i + j) --> ?P i))) *) |
731 (ALL i. (EX j. number_of ?k < j & j <= 0 & ?n = number_of ?k * i + j) --> ?P i))) *) |
732 | (Const ("Divides.div", |
732 | (Const ("Divides.div_class.div", |
733 Type ("fun", [Type ("IntDef.int", []), _])), [t1, t2 as (number_of $ k)]) => |
733 Type ("fun", [Type ("IntDef.int", []), _])), [t1, t2 as (number_of $ k)]) => |
734 let |
734 let |
735 val rev_terms = rev terms |
735 val rev_terms = rev terms |
736 val zero = Const ("HOL.zero", split_type) |
736 val zero = Const (@{const_name HOL.zero}, split_type) |
737 val i = Bound 1 |
737 val i = Bound 1 |
738 val j = Bound 0 |
738 val j = Bound 0 |
739 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
739 val terms1 = map (subst_term [(split_term, zero)]) rev_terms |
740 val terms2_3 = map (subst_term [(incr_boundvars 2 split_term, i)]) |
740 val terms2_3 = map (subst_term [(incr_boundvars 2 split_term, i)]) |
741 (map (incr_boundvars 2) rev_terms) |
741 (map (incr_boundvars 2) rev_terms) |
742 val t1' = incr_boundvars 2 t1 |
742 val t1' = incr_boundvars 2 t1 |
743 val (t2' as (_ $ k')) = incr_boundvars 2 t2 |
743 val (t2' as (_ $ k')) = incr_boundvars 2 t2 |
744 val iszero_t2 = Const ("IntDef.iszero", split_type --> HOLogic.boolT) $ t2 |
744 val iszero_t2 = Const ("IntDef.iszero", split_type --> HOLogic.boolT) $ t2 |
745 val neg_minus_k = Const ("IntDef.neg", split_type --> HOLogic.boolT) $ |
745 val neg_minus_k = Const ("IntDef.neg", split_type --> HOLogic.boolT) $ |
746 (number_of $ |
746 (number_of $ |
747 (Const ("HOL.uminus", |
747 (Const (@{const_name HOL.uminus}, |
748 HOLogic.intT --> HOLogic.intT) $ k')) |
748 HOLogic.intT --> HOLogic.intT) $ k')) |
749 val zero_leq_j = Const ("Orderings.less_eq", |
749 val zero_leq_j = Const (@{const_name Orderings.less_eq}, |
750 split_type --> split_type --> HOLogic.boolT) $ zero $ j |
750 split_type --> split_type --> HOLogic.boolT) $ zero $ j |
751 val j_lt_t2 = Const ("Orderings.less", |
751 val j_lt_t2 = Const (@{const_name Orderings.less}, |
752 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
752 split_type --> split_type--> HOLogic.boolT) $ j $ t2' |
753 val t1_eq_t2_times_i_plus_j = Const ("op =", |
753 val t1_eq_t2_times_i_plus_j = Const ("op =", |
754 split_type --> split_type --> HOLogic.boolT) $ t1' $ |
754 split_type --> split_type --> HOLogic.boolT) $ t1' $ |
755 (Const ("HOL.plus", split_type --> split_type --> split_type) $ |
755 (Const (@{const_name HOL.plus}, split_type --> split_type --> split_type) $ |
756 (Const ("HOL.times", |
756 (Const (@{const_name HOL.times}, |
757 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
757 split_type --> split_type --> split_type) $ t2' $ i) $ j) |
758 val neg_t2 = Const ("IntDef.neg", split_type --> HOLogic.boolT) $ t2' |
758 val neg_t2 = Const ("IntDef.neg", split_type --> HOLogic.boolT) $ t2' |
759 val t2_lt_j = Const ("Orderings.less", |
759 val t2_lt_j = Const (@{const_name Orderings.less}, |
760 split_type --> split_type--> HOLogic.boolT) $ t2' $ j |
760 split_type --> split_type--> HOLogic.boolT) $ t2' $ j |
761 val j_leq_zero = Const ("Orderings.less_eq", |
761 val j_leq_zero = Const (@{const_name Orderings.less_eq}, |
762 split_type --> split_type --> HOLogic.boolT) $ j $ zero |
762 split_type --> split_type --> HOLogic.boolT) $ j $ zero |
763 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
763 val not_false = HOLogic.mk_Trueprop (HOLogic.Not $ HOLogic.false_const) |
764 val subgoal1 = (HOLogic.mk_Trueprop iszero_t2) :: terms1 @ [not_false] |
764 val subgoal1 = (HOLogic.mk_Trueprop iszero_t2) :: terms1 @ [not_false] |
765 val subgoal2 = (HOLogic.mk_Trueprop neg_minus_k) |
765 val subgoal2 = (HOLogic.mk_Trueprop neg_minus_k) |
766 :: terms2_3 |
766 :: terms2_3 |
1007 fun antisym_eq prems thm = |
1007 fun antisym_eq prems thm = |
1008 let |
1008 let |
1009 val r = #prop(rep_thm thm); |
1009 val r = #prop(rep_thm thm); |
1010 in |
1010 in |
1011 case r of |
1011 case r of |
1012 Tr $ ((c as Const("Orderings.less_eq",T)) $ s $ t) => |
1012 Tr $ ((c as Const(@{const_name Orderings.less_eq},T)) $ s $ t) => |
1013 let val r' = Tr $ (c $ t $ s) |
1013 let val r' = Tr $ (c $ t $ s) |
1014 in |
1014 in |
1015 case Library.find_first (prp r') prems of |
1015 case Library.find_first (prp r') prems of |
1016 NONE => |
1016 NONE => |
1017 let val r' = Tr $ (HOLogic.Not $ (Const("Orderings.less",T) $ s $ t)) |
1017 let val r' = Tr $ (HOLogic.Not $ (Const(@{const_name Orderings.less},T) $ s $ t)) |
1018 in case Library.find_first (prp r') prems of |
1018 in case Library.find_first (prp r') prems of |
1019 NONE => [] |
1019 NONE => [] |
1020 | SOME thm' => [(thm' RS not_lessD) RS (thm RS antisym)] |
1020 | SOME thm' => [(thm' RS not_lessD) RS (thm RS antisym)] |
1021 end |
1021 end |
1022 | SOME thm' => [thm' RS (thm RS antisym)] |
1022 | SOME thm' => [thm' RS (thm RS antisym)] |
1023 end |
1023 end |
1024 | Tr $ (Const("Not",_) $ (Const("Orderings.less",T) $ s $ t)) => |
1024 | Tr $ (Const("Not",_) $ (Const(@{const_name Orderings.less},T) $ s $ t)) => |
1025 let val r' = Tr $ (Const("Orderings.less_eq",T) $ s $ t) |
1025 let val r' = Tr $ (Const(@{const_name Orderings.less_eq},T) $ s $ t) |
1026 in |
1026 in |
1027 case Library.find_first (prp r') prems of |
1027 case Library.find_first (prp r') prems of |
1028 NONE => |
1028 NONE => |
1029 let val r' = Tr $ (HOLogic.Not $ (Const("Orderings.less",T) $ t $ s)) |
1029 let val r' = Tr $ (HOLogic.Not $ (Const(@{const_name Orderings.less},T) $ t $ s)) |
1030 in case Library.find_first (prp r') prems of |
1030 in case Library.find_first (prp r') prems of |
1031 NONE => [] |
1031 NONE => [] |
1032 | SOME thm' => |
1032 | SOME thm' => |
1033 [(thm' RS not_lessD) RS ((thm RS not_lessD) RS antisym)] |
1033 [(thm' RS not_lessD) RS ((thm RS not_lessD) RS antisym)] |
1034 end |
1034 end |