583 else error "Cannot replay Metis proof in Isabelle: Out of sync." |
583 else error "Cannot replay Metis proof in Isabelle: Out of sync." |
584 in (fol_th, th) :: thpairs end |
584 in (fol_th, th) :: thpairs end |
585 |
585 |
586 fun term_instantiate thy = cterm_instantiate o map (pairself (cterm_of thy)) |
586 fun term_instantiate thy = cterm_instantiate o map (pairself (cterm_of thy)) |
587 |
587 |
588 (* In principle, it should be sufficient to apply "assume_tac" to unify the |
|
589 conclusion with one of the premises. However, in practice, this is unreliable |
|
590 because of the mildly higher-order nature of the unification problems. |
|
591 Typical constraints are of the form |
|
592 "?SK_a_b_c_x SK_d_e_f_y ... SK_a_b_c_x ... SK_g_h_i_z =?= SK_a_b_c_x", |
|
593 where the nonvariables are goal parameters. *) |
|
594 (* FIXME: ### try Pattern.match instead *) |
|
595 fun unify_first_prem_with_concl thy i th = |
|
596 let |
|
597 val goal = Logic.get_goal (prop_of th) i |> Envir.beta_eta_contract |
|
598 val prem = goal |> Logic.strip_assums_hyp |> hd |
|
599 val concl = goal |> Logic.strip_assums_concl |
|
600 fun pair_untyped_aconv (t1, t2) (u1, u2) = |
|
601 untyped_aconv t1 u1 andalso untyped_aconv t2 u2 |
|
602 fun add_terms tp inst = |
|
603 if exists (pair_untyped_aconv tp) inst then inst |
|
604 else tp :: map (apsnd (subst_atomic [tp])) inst |
|
605 fun is_flex t = |
|
606 case strip_comb t of |
|
607 (Var _, args) => forall is_Bound args |
|
608 | _ => false |
|
609 fun unify_flex flex rigid = |
|
610 case strip_comb flex of |
|
611 (Var (z as (_, T)), args) => |
|
612 add_terms (Var z, |
|
613 fold_rev (curry absdummy) (take (length args) (binder_types T)) rigid) |
|
614 | _ => raise TERM ("unify_flex: expected flex", [flex]) |
|
615 fun unify_potential_flex comb atom = |
|
616 if is_flex comb then unify_flex comb atom |
|
617 else if is_Var atom then add_terms (atom, comb) |
|
618 else raise TERM ("unify_potential_flex", [comb, atom]) |
|
619 fun unify_terms (t, u) = |
|
620 case (t, u) of |
|
621 (t1 $ t2, u1 $ u2) => |
|
622 if is_flex t then unify_flex t u |
|
623 else if is_flex u then unify_flex u t |
|
624 else fold unify_terms [(t1, u1), (t2, u2)] |
|
625 | (_ $ _, _) => unify_potential_flex t u |
|
626 | (_, _ $ _) => unify_potential_flex u t |
|
627 | (Var _, _) => add_terms (t, u) |
|
628 | (_, Var _) => add_terms (u, t) |
|
629 | _ => if untyped_aconv t u then I else raise TERM ("unify_terms", [t, u]) |
|
630 in th |> term_instantiate thy (unify_terms (prem, concl) []) end |
|
631 |
|
632 val copy_prem = @{lemma "P ==> (P ==> P ==> Q) ==> Q" by fast} |
588 val copy_prem = @{lemma "P ==> (P ==> P ==> Q) ==> Q" by fast} |
633 |
589 |
634 fun copy_prems_tac [] ns i = |
590 fun copy_prems_tac [] ns i = |
635 if forall (curry (op =) 1) ns then all_tac else copy_prems_tac (rev ns) [] i |
591 if forall (curry (op =) 1) ns then all_tac else copy_prems_tac (rev ns) [] i |
636 | copy_prems_tac (1 :: ms) ns i = |
592 | copy_prems_tac (1 :: ms) ns i = |
728 if prop_of prems_imp_false aconv @{prop False} then |
684 if prop_of prems_imp_false aconv @{prop False} then |
729 prems_imp_false |
685 prems_imp_false |
730 else |
686 else |
731 let |
687 let |
732 val thy = ProofContext.theory_of ctxt |
688 val thy = ProofContext.theory_of ctxt |
733 (* distinguish variables with same name but different types *) |
|
734 (* ### FIXME: needed? *) |
|
735 val prems_imp_false' = |
|
736 prems_imp_false |> try (forall_intr_vars #> gen_all) |
|
737 |> the_default prems_imp_false |
|
738 val prems_imp_false = |
|
739 if prop_of prems_imp_false aconv prop_of prems_imp_false' then |
|
740 prems_imp_false |
|
741 else |
|
742 prems_imp_false' |
|
743 fun match_term p = |
689 fun match_term p = |
744 let |
690 let |
745 val (tyenv, tenv) = |
691 val (tyenv, tenv) = |
746 Pattern.first_order_match thy p (Vartab.empty, Vartab.empty) |
692 Pattern.first_order_match thy p (Vartab.empty, Vartab.empty) |
747 val tsubst = |
693 val tsubst = |
830 THEN release_clusters_tac thy ax_counts substs ordered_clusters 1 |
776 THEN release_clusters_tac thy ax_counts substs ordered_clusters 1 |
831 THEN match_tac [prems_imp_false] 1 |
777 THEN match_tac [prems_imp_false] 1 |
832 THEN ALLGOALS (fn i => |
778 THEN ALLGOALS (fn i => |
833 rtac @{thm Meson.skolem_COMBK_I} i |
779 rtac @{thm Meson.skolem_COMBK_I} i |
834 THEN rotate_tac (rotation_for_subgoal i) i |
780 THEN rotate_tac (rotation_for_subgoal i) i |
835 (* THEN PRIMITIVE (unify_first_prem_with_concl thy i) FIXME: needed? *) |
|
836 THEN assume_tac i))) |
781 THEN assume_tac i))) |
837 handle ERROR _ => |
782 handle ERROR _ => |
838 error ("Cannot replay Metis proof in Isabelle:\n\ |
783 error ("Cannot replay Metis proof in Isabelle:\n\ |
839 \Error when discharging Skolem assumptions.") |
784 \Error when discharging Skolem assumptions.") |
840 end |
785 end |