1500 end) (recTs ~~ rec_result_Ts ~~ rec_sets ~~ (1 upto length recTs))))) |
1500 end) (recTs ~~ rec_result_Ts ~~ rec_sets ~~ (1 upto length recTs))))) |
1501 (fn fins => (rtac rec_induct THEN_ALL_NEW cut_facts_tac fins) 1 THEN REPEAT |
1501 (fn fins => (rtac rec_induct THEN_ALL_NEW cut_facts_tac fins) 1 THEN REPEAT |
1502 (NominalPermeq.finite_guess_tac (HOL_ss addsimps [fs_name]) 1)))) |
1502 (NominalPermeq.finite_guess_tac (HOL_ss addsimps [fs_name]) 1)))) |
1503 end) dt_atomTs; |
1503 end) dt_atomTs; |
1504 |
1504 |
1505 (** uniqueness **) |
1505 (** freshness **) |
1506 |
1506 |
1507 val fresh_prems = List.concat (map (fn aT => |
1507 val perm_fresh_fresh = PureThy.get_thms thy11 (Name "perm_fresh_fresh"); |
|
1508 val perm_swap = PureThy.get_thms thy11 (Name "perm_swap"); |
|
1509 |
|
1510 fun perm_of_pair (x, y) = |
|
1511 let |
|
1512 val T = fastype_of x; |
|
1513 val pT = mk_permT T |
|
1514 in Const ("List.list.Cons", HOLogic.mk_prodT (T, T) --> pT --> pT) $ |
|
1515 HOLogic.mk_prod (x, y) $ Const ("List.list.Nil", pT) |
|
1516 end; |
|
1517 |
|
1518 val finite_premss = map (fn aT => |
1508 map (fn (f, T) => HOLogic.mk_Trueprop (HOLogic.mk_mem |
1519 map (fn (f, T) => HOLogic.mk_Trueprop (HOLogic.mk_mem |
1509 (Const ("Nominal.supp", T --> HOLogic.mk_setT aT) $ f, |
1520 (Const ("Nominal.supp", T --> HOLogic.mk_setT aT) $ f, |
1510 Const ("Finite_Set.Finites", HOLogic.mk_setT (HOLogic.mk_setT aT))))) |
1521 Const ("Finite_Set.Finites", HOLogic.mk_setT (HOLogic.mk_setT aT))))) |
1511 (rec_fns ~~ rec_fn_Ts)) dt_atomTs); |
1522 (rec_fns ~~ rec_fn_Ts)) dt_atomTs; |
|
1523 |
|
1524 val rec_fresh_thms = map (fn ((aT, eqvt_ths), finite_prems) => |
|
1525 let |
|
1526 val name = Sign.base_name (fst (dest_Type aT)); |
|
1527 val fs_name = PureThy.get_thm thy11 (Name ("fs_" ^ name ^ "1")); |
|
1528 val a = Free ("a", aT); |
|
1529 val freshs = map (fn (f, fT) => HOLogic.mk_Trueprop |
|
1530 (Const ("Nominal.fresh", aT --> fT --> HOLogic.boolT) $ a $ f)) |
|
1531 (rec_fns ~~ rec_fn_Ts) |
|
1532 in |
|
1533 map (fn (((T, U), R), eqvt_th) => |
|
1534 let |
|
1535 val x = Free ("x", T); |
|
1536 val y = Free ("y", U); |
|
1537 val y' = Free ("y'", U) |
|
1538 in |
|
1539 standard (Goal.prove (Context.init_proof thy11) [] (finite_prems @ |
|
1540 [HOLogic.mk_Trueprop (HOLogic.mk_mem |
|
1541 (HOLogic.mk_prod (x, y), R)), |
|
1542 HOLogic.mk_Trueprop (HOLogic.mk_all ("y'", U, |
|
1543 HOLogic.mk_imp (HOLogic.mk_mem |
|
1544 (HOLogic.mk_prod (x, y'), R), |
|
1545 HOLogic.mk_eq (y', y)))), |
|
1546 HOLogic.mk_Trueprop (Const ("Nominal.fresh", |
|
1547 aT --> T --> HOLogic.boolT) $ a $ x)] @ |
|
1548 freshs) |
|
1549 (HOLogic.mk_Trueprop (Const ("Nominal.fresh", |
|
1550 aT --> U --> HOLogic.boolT) $ a $ y)) |
|
1551 (fn {prems, context} => |
|
1552 let |
|
1553 val (finite_prems, rec_prem :: unique_prem :: |
|
1554 fresh_prems) = chop (length finite_prems) prems; |
|
1555 val unique_prem' = unique_prem RS spec RS mp; |
|
1556 val unique = [unique_prem', unique_prem' RS sym] MRS trans; |
|
1557 val _ $ (_ $ (_ $ S $ _)) $ _ = prop_of supports_fresh; |
|
1558 val tuple = foldr1 HOLogic.mk_prod (x :: rec_fns) |
|
1559 in EVERY |
|
1560 [rtac (Drule.cterm_instantiate |
|
1561 [(cterm_of thy11 S, |
|
1562 cterm_of thy11 (Const ("Nominal.supp", |
|
1563 fastype_of tuple --> HOLogic.mk_setT aT) $ tuple))] |
|
1564 supports_fresh) 1, |
|
1565 simp_tac (HOL_basic_ss addsimps |
|
1566 [supports_def, symmetric fresh_def, fresh_prod]) 1, |
|
1567 REPEAT_DETERM (resolve_tac [allI, impI] 1), |
|
1568 REPEAT_DETERM (etac conjE 1), |
|
1569 rtac unique 1, |
|
1570 SUBPROOF (fn {prems = prems', params = [a, b], ...} => EVERY |
|
1571 [cut_facts_tac [rec_prem] 1, |
|
1572 rtac (Thm.instantiate ([], |
|
1573 [(cterm_of thy11 (Var (("pi", 0), mk_permT aT)), |
|
1574 cterm_of thy11 (perm_of_pair (term_of a, term_of b)))]) eqvt_th) 1, |
|
1575 asm_simp_tac (HOL_ss addsimps |
|
1576 (prems' @ perm_swap @ perm_fresh_fresh)) 1]) context 1, |
|
1577 rtac rec_prem 1, |
|
1578 simp_tac (HOL_ss addsimps (fs_name :: |
|
1579 supp_prod :: finite_Un :: finite_prems)) 1, |
|
1580 simp_tac (HOL_ss addsimps (symmetric fresh_def :: |
|
1581 fresh_prod :: fresh_prems)) 1] |
|
1582 end)) |
|
1583 end) (recTs ~~ rec_result_Ts ~~ rec_sets ~~ eqvt_ths) |
|
1584 end) (dt_atomTs ~~ rec_equiv_thms' ~~ finite_premss); |
|
1585 |
|
1586 (** uniqueness **) |
|
1587 |
|
1588 val exists_fresh = PureThy.get_thms thy11 (Name "exists_fresh"); |
|
1589 val fs_atoms = map (fn Type (s, _) => PureThy.get_thm thy11 |
|
1590 (Name ("fs_" ^ Sign.base_name s ^ "1"))) dt_atomTs; |
|
1591 val fresh_atm = PureThy.get_thms thy11 (Name "fresh_atm"); |
|
1592 val calc_atm = PureThy.get_thms thy11 (Name "calc_atm"); |
|
1593 val fresh_left = PureThy.get_thms thy11 (Name "fresh_left"); |
1512 |
1594 |
1513 val fun_tuple = foldr1 HOLogic.mk_prod rec_fns; |
1595 val fun_tuple = foldr1 HOLogic.mk_prod rec_fns; |
1514 val fun_tupleT = fastype_of fun_tuple; |
1596 val fun_tupleT = fastype_of fun_tuple; |
1515 val rec_unique_frees = |
1597 val rec_unique_frees = |
1516 DatatypeProp.indexify_names (replicate (length recTs) "x") ~~ recTs; |
1598 DatatypeProp.indexify_names (replicate (length recTs) "x") ~~ recTs; |
1530 Abs ("z", HOLogic.unitT, absfree (x, U, Q)))) |
1613 Abs ("z", HOLogic.unitT, absfree (x, U, Q)))) |
1531 (pnames ~~ recTs ~~ rec_unique_frees ~~ rec_unique_concls) @ |
1614 (pnames ~~ recTs ~~ rec_unique_frees ~~ rec_unique_concls) @ |
1532 map (fn (s, T) => (Var ((s, 0), Logic.varifyT T), Free (s, T))) |
1615 map (fn (s, T) => (Var ((s, 0), Logic.varifyT T), Free (s, T))) |
1533 rec_unique_frees)) induct_aux; |
1616 rec_unique_frees)) induct_aux; |
1534 |
1617 |
1535 val rec_unique = map standard (split_conj_thm (Goal.prove_global thy11 [] |
1618 fun obtain_fresh_name vs ths rec_fin_supp T (freshs1, freshs2, ctxt) = |
1536 (fresh_prems @ rec_prems @ rec_prems') |
1619 let |
|
1620 val p = foldr1 HOLogic.mk_prod (vs @ freshs1); |
|
1621 val ex = Goal.prove ctxt [] [] (HOLogic.mk_Trueprop |
|
1622 (HOLogic.exists_const T $ Abs ("x", T, |
|
1623 Const ("Nominal.fresh", T --> fastype_of p --> HOLogic.boolT) $ |
|
1624 Bound 0 $ p))) |
|
1625 (fn _ => EVERY |
|
1626 [cut_facts_tac ths 1, |
|
1627 REPEAT_DETERM (dresolve_tac (the (AList.lookup op = rec_fin_supp T)) 1), |
|
1628 resolve_tac exists_fresh 1, |
|
1629 asm_simp_tac (HOL_ss addsimps (supp_prod :: finite_Un :: fs_atoms)) 1]); |
|
1630 val (([cx], ths), ctxt') = Obtain.result |
|
1631 (fn _ => EVERY |
|
1632 [etac exE 1, |
|
1633 full_simp_tac (HOL_ss addsimps (fresh_prod :: fresh_atm)) 1, |
|
1634 REPEAT (etac conjE 1)]) |
|
1635 [ex] ctxt |
|
1636 in (freshs1 @ [term_of cx], freshs2 @ ths, ctxt') end; |
|
1637 |
|
1638 val rec_unique = map standard (split_conj_thm (Goal.prove |
|
1639 (Context.init_proof thy11) [] |
|
1640 (List.concat finite_premss @ rec_prems @ rec_prems') |
1537 (HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj rec_unique_concls)) |
1641 (HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj rec_unique_concls)) |
1538 (fn ths => |
1642 (fn {prems, context} => |
1539 let |
1643 let |
1540 val k = length rec_fns; |
1644 val k = length rec_fns; |
1541 val (finite_thss, ths1) = funpow (length dt_atomTs) (fn (xss, ys) => |
1645 val (finite_thss, ths1) = fold_map (fn T => fn xs => |
1542 apfst (curry op @ xss o single) (chop k ys)) ([], ths); |
1646 apfst (pair T) (chop k xs)) dt_atomTs prems; |
1543 val (P_ind_ths, ths2) = chop k ths1; |
1647 val (P_ind_ths, ths2) = chop k ths1; |
1544 val P_ths = map (fn th => th RS mp) (split_conj_thm |
1648 val P_ths = map (fn th => th RS mp) (split_conj_thm |
1545 (Goal.prove (Context.init_proof thy11) |
1649 (Goal.prove context |
1546 (map fst (rec_unique_frees @ rec_unique_frees')) [] |
1650 (map fst (rec_unique_frees @ rec_unique_frees')) [] |
1547 (HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj |
1651 (HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj |
1548 (map (fn (((x, y), S), P) => HOLogic.mk_imp (HOLogic.mk_mem |
1652 (map (fn (((x, y), S), P) => HOLogic.mk_imp (HOLogic.mk_mem |
1549 (HOLogic.mk_prod (Free x, Free y), S), P $ (Free y))) |
1653 (HOLogic.mk_prod (Free x, Free y), S), P $ (Free y))) |
1550 (rec_unique_frees ~~ rec_unique_frees' ~~ rec_sets ~~ rec_preds)))) |
1654 (rec_unique_frees ~~ rec_unique_frees' ~~ rec_sets ~~ rec_preds)))) |
1551 (fn _ => |
1655 (fn _ => |
1552 rtac rec_induct 1 THEN |
1656 rtac rec_induct 1 THEN |
1553 REPEAT ((resolve_tac P_ind_ths THEN_ALL_NEW assume_tac) 1)))) |
1657 REPEAT ((resolve_tac P_ind_ths THEN_ALL_NEW assume_tac) 1)))); |
|
1658 val rec_fin_supp_thms' = map |
|
1659 (fn (ths, (T, fin_ths)) => (T, map (curry op MRS fin_ths) ths)) |
|
1660 (rec_fin_supp_thms ~~ finite_thss); |
|
1661 val fcbs = List.concat (map split_conj_thm ths2); |
1554 in EVERY |
1662 in EVERY |
1555 ([rtac induct_aux_rec 1] @ |
1663 ([rtac induct_aux_rec 1] @ |
1556 List.concat (map (fn finite_ths => |
1664 List.concat (map (fn (_, finite_ths) => |
1557 [cut_facts_tac finite_ths 1, |
1665 [cut_facts_tac finite_ths 1, |
1558 asm_simp_tac (HOL_ss addsimps [supp_prod, finite_Un]) 1]) finite_thss) @ |
1666 asm_simp_tac (HOL_ss addsimps [supp_prod, finite_Un]) 1]) finite_thss) @ |
1559 [ALLGOALS (full_simp_tac (HOL_ss addsimps [symmetric fresh_def, supp_prod, Un_iff])), |
1667 [ALLGOALS (EVERY' |
1560 print_tac "after application of induction theorem", |
1668 [full_simp_tac (HOL_ss addsimps [symmetric fresh_def, supp_prod, Un_iff]), |
1561 setmp quick_and_dirty true (SkipProof.cheat_tac thy11) (** FIXME !! **)]) |
1669 REPEAT_DETERM o eresolve_tac [conjE, ex1E], |
|
1670 rtac ex1I, |
|
1671 resolve_tac rec_intrs THEN_ALL_NEW atac, |
|
1672 rotate_tac ~1, |
|
1673 (DETERM o eresolve_tac rec_elims) THEN_ALL_NEW full_simp_tac |
|
1674 (HOL_ss addsimps (Pair_eq :: List.concat distinct_thms)), |
|
1675 TRY o (etac conjE THEN' hyp_subst_tac)])] @ |
|
1676 map (fn idxs => SUBPROOF |
|
1677 (fn {asms, concl, prems = prems', params, context = context', ...} => |
|
1678 let |
|
1679 val (_, prem) = split_last prems'; |
|
1680 val _ $ (_ $ lhs $ rhs) = prop_of prem; |
|
1681 val _ $ (_ $ lhs' $ rhs') = term_of concl; |
|
1682 val rT = fastype_of lhs'; |
|
1683 val (c, cargsl) = strip_comb lhs; |
|
1684 val cargsl' = partition_cargs idxs cargsl; |
|
1685 val boundsl = List.concat (map fst cargsl'); |
|
1686 val (_, cargsr) = strip_comb rhs; |
|
1687 val cargsr' = partition_cargs idxs cargsr; |
|
1688 val boundsr = List.concat (map fst cargsr'); |
|
1689 val (params1, _ :: params2) = |
|
1690 chop (length params div 2) (map term_of params); |
|
1691 val params' = params1 @ params2; |
|
1692 val rec_prems = filter (fn th => case prop_of th of |
|
1693 _ $ (Const ("op :", _) $ _ $ _) => true | _ => false) prems'; |
|
1694 val fresh_prems = filter (fn th => case prop_of th of |
|
1695 _ $ (Const ("Nominal.fresh", _) $ _ $ _) => true |
|
1696 | _ $ (Const ("Not", _) $ _) => true |
|
1697 | _ => false) prems'; |
|
1698 val Ts = map fastype_of boundsl; |
|
1699 |
|
1700 val _ = warning "step 1: obtaining fresh names"; |
|
1701 val (freshs1, freshs2, context'') = fold |
|
1702 (obtain_fresh_name (rec_fns @ params') |
|
1703 (List.concat (map snd finite_thss) @ rec_prems) |
|
1704 rec_fin_supp_thms') |
|
1705 Ts ([], [], context'); |
|
1706 val pi1 = map perm_of_pair (boundsl ~~ freshs1); |
|
1707 val rpi1 = rev pi1; |
|
1708 val pi2 = map perm_of_pair (boundsr ~~ freshs1); |
|
1709 |
|
1710 fun mk_not_sym ths = List.concat (map (fn th => |
|
1711 case prop_of th of |
|
1712 _ $ (Const ("Not", _) $ _) => [th, th RS not_sym] |
|
1713 | _ => [th]) ths); |
|
1714 val fresh_prems' = mk_not_sym fresh_prems; |
|
1715 val freshs2' = mk_not_sym freshs2; |
|
1716 |
|
1717 (** as, bs, cs # K as ts, K bs us **) |
|
1718 val _ = warning "step 2: as, bs, cs # K as ts, K bs us"; |
|
1719 val prove_fresh_ss = HOL_ss addsimps |
|
1720 (finite_Diff :: List.concat fresh_thms @ |
|
1721 fs_atoms @ abs_fresh @ abs_supp @ fresh_atm); |
|
1722 (* FIXME: avoid asm_full_simp_tac ? *) |
|
1723 fun prove_fresh ths y x = Goal.prove context'' [] [] |
|
1724 (HOLogic.mk_Trueprop (Const ("Nominal.fresh", |
|
1725 fastype_of x --> fastype_of y --> HOLogic.boolT) $ x $ y)) |
|
1726 (fn _ => cut_facts_tac ths 1 THEN asm_full_simp_tac prove_fresh_ss 1); |
|
1727 val constr_fresh_thms = |
|
1728 map (prove_fresh fresh_prems lhs) boundsl @ |
|
1729 map (prove_fresh fresh_prems rhs) boundsr @ |
|
1730 map (prove_fresh freshs2 lhs) freshs1 @ |
|
1731 map (prove_fresh freshs2 rhs) freshs1; |
|
1732 |
|
1733 (** pi1 o (K as ts) = pi2 o (K bs us) **) |
|
1734 val _ = warning "step 3: pi1 o (K as ts) = pi2 o (K bs us)"; |
|
1735 val pi1_pi2_eq = Goal.prove context'' [] [] |
|
1736 (HOLogic.mk_Trueprop (HOLogic.mk_eq |
|
1737 (foldr (mk_perm []) lhs pi1, foldr (mk_perm []) rhs pi2))) |
|
1738 (fn _ => EVERY |
|
1739 [cut_facts_tac constr_fresh_thms 1, |
|
1740 asm_simp_tac (HOL_basic_ss addsimps perm_fresh_fresh) 1, |
|
1741 rtac prem 1]); |
|
1742 |
|
1743 (** pi1 o ts = pi2 o us **) |
|
1744 val _ = warning "step 4: pi1 o ts = pi2 o us"; |
|
1745 val pi1_pi2_eqs = map (fn (t, u) => |
|
1746 Goal.prove context'' [] [] |
|
1747 (HOLogic.mk_Trueprop (HOLogic.mk_eq |
|
1748 (foldr (mk_perm []) t pi1, foldr (mk_perm []) u pi2))) |
|
1749 (fn _ => EVERY |
|
1750 [cut_facts_tac [pi1_pi2_eq] 1, |
|
1751 asm_full_simp_tac (HOL_ss addsimps |
|
1752 (calc_atm @ List.concat perm_simps' @ |
|
1753 fresh_prems' @ freshs2' @ abs_perm @ |
|
1754 alpha @ List.concat inject_thms)) 1])) |
|
1755 (map snd cargsl' ~~ map snd cargsr'); |
|
1756 |
|
1757 (** pi1^-1 o pi2 o us = ts **) |
|
1758 val _ = warning "step 5: pi1^-1 o pi2 o us = ts"; |
|
1759 val rpi1_pi2_eqs = map (fn ((t, u), eq) => |
|
1760 Goal.prove context'' [] [] |
|
1761 (HOLogic.mk_Trueprop (HOLogic.mk_eq |
|
1762 (foldr (mk_perm []) u (rpi1 @ pi2), t))) |
|
1763 (fn _ => simp_tac (HOL_ss addsimps |
|
1764 ((eq RS sym) :: perm_swap)) 1)) |
|
1765 (map snd cargsl' ~~ map snd cargsr' ~~ pi1_pi2_eqs); |
|
1766 |
|
1767 val (rec_prems1, rec_prems2) = |
|
1768 chop (length rec_prems div 2) rec_prems; |
|
1769 |
|
1770 (** (ts, pi1^-1 o pi2 o vs) in rec_set **) |
|
1771 val _ = warning "step 6: (ts, pi1^-1 o pi2 o vs) in rec_set"; |
|
1772 val rec_prems' = map (fn th => |
|
1773 let |
|
1774 val _ $ (_ $ (_ $ x $ y) $ S) = prop_of th; |
|
1775 val k = find_index (equal S) rec_sets; |
|
1776 val pi = rpi1 @ pi2; |
|
1777 fun mk_pi z = foldr (mk_perm []) z pi; |
|
1778 fun eqvt_tac p = |
|
1779 let |
|
1780 val U as Type (_, [Type (_, [T, _])]) = fastype_of p; |
|
1781 val l = find_index (equal T) dt_atomTs; |
|
1782 val th = List.nth (List.nth (rec_equiv_thms', l), k); |
|
1783 val th' = Thm.instantiate ([], |
|
1784 [(cterm_of thy11 (Var (("pi", 0), U)), |
|
1785 cterm_of thy11 p)]) th; |
|
1786 in rtac th' 1 end; |
|
1787 val th' = Goal.prove context'' [] [] |
|
1788 (HOLogic.mk_Trueprop (HOLogic.mk_mem |
|
1789 (HOLogic.mk_prod (mk_pi x, mk_pi y), S))) |
|
1790 (fn _ => EVERY |
|
1791 (map eqvt_tac pi @ |
|
1792 [simp_tac (HOL_ss addsimps (fresh_prems' @ freshs2' @ |
|
1793 perm_swap @ perm_fresh_fresh)) 1, |
|
1794 rtac th 1])) |
|
1795 in |
|
1796 Simplifier.simplify |
|
1797 (HOL_basic_ss addsimps rpi1_pi2_eqs) th' |
|
1798 end) rec_prems2; |
|
1799 |
|
1800 val ihs = filter (fn th => case prop_of th of |
|
1801 _ $ (Const ("All", _) $ _) => true | _ => false) prems'; |
|
1802 |
|
1803 (** pi1 o rs = p2 o vs , rs = pi1^-1 o pi2 o vs **) |
|
1804 val _ = warning "step 7: pi1 o rs = p2 o vs , rs = pi1^-1 o pi2 o vs"; |
|
1805 val (rec_eqns1, rec_eqns2) = ListPair.unzip (map (fn (th, ih) => |
|
1806 let |
|
1807 val th' = th RS (ih RS spec RS mp) RS sym; |
|
1808 val _ $ (_ $ lhs $ rhs) = prop_of th'; |
|
1809 fun strip_perm (_ $ _ $ t) = strip_perm t |
|
1810 | strip_perm t = t; |
|
1811 in |
|
1812 (Goal.prove context'' [] [] |
|
1813 (HOLogic.mk_Trueprop (HOLogic.mk_eq |
|
1814 (foldr (mk_perm []) lhs pi1, |
|
1815 foldr (mk_perm []) (strip_perm rhs) pi2))) |
|
1816 (fn _ => simp_tac (HOL_basic_ss addsimps |
|
1817 (th' :: perm_swap)) 1), |
|
1818 th') |
|
1819 end) (rec_prems' ~~ ihs)); |
|
1820 |
|
1821 (** as # rs , bs # vs **) |
|
1822 val _ = warning "step 8: as # rs , bs # vs"; |
|
1823 val (rec_freshs1, rec_freshs2) = ListPair.unzip (List.concat |
|
1824 (map (fn (((rec_prem, rec_prem'), eqn), ih) => |
|
1825 let |
|
1826 val _ $ (_ $ (_ $ x $ (y as Free (_, T))) $ S) = |
|
1827 prop_of rec_prem; |
|
1828 val _ $ (_ $ (_ $ _ $ y') $ _) = prop_of rec_prem'; |
|
1829 val k = find_index (equal S) rec_sets; |
|
1830 val atoms = List.concat (List.mapPartial |
|
1831 (fn ((bs, z), (bs', _)) => |
|
1832 if z = x then NONE else SOME (bs ~~ bs')) |
|
1833 (cargsl' ~~ cargsr')) |
|
1834 in |
|
1835 map (fn (a as Free (_, aT), b) => |
|
1836 let |
|
1837 val l = find_index (equal aT) dt_atomTs; |
|
1838 val th = Goal.prove context'' [] [] |
|
1839 (HOLogic.mk_Trueprop (Const ("Nominal.fresh", |
|
1840 aT --> T --> HOLogic.boolT) $ a $ y)) |
|
1841 (fn _ => EVERY |
|
1842 (rtac (List.nth (List.nth (rec_fresh_thms, l), k)) 1 :: |
|
1843 map (fn th => rtac th 1) |
|
1844 (snd (List.nth (finite_thss, l))) @ |
|
1845 [rtac rec_prem 1, rtac ih 1, |
|
1846 REPEAT_DETERM (resolve_tac fresh_prems 1)])); |
|
1847 val th' = Goal.prove context'' [] [] |
|
1848 (HOLogic.mk_Trueprop (Const ("Nominal.fresh", |
|
1849 aT --> T --> HOLogic.boolT) $ b $ y')) |
|
1850 (fn _ => cut_facts_tac [th] 1 THEN |
|
1851 asm_full_simp_tac (HOL_ss addsimps (eqn :: |
|
1852 fresh_left @ fresh_prems' @ freshs2' @ |
|
1853 rev_simps @ app_simps @ calc_atm)) 1) |
|
1854 in (th, th') end) atoms |
|
1855 end) (rec_prems1 ~~ rec_prems2 ~~ rec_eqns2 ~~ ihs))); |
|
1856 |
|
1857 (** as # fK as ts rs , bs # fK bs us vs **) |
|
1858 val _ = warning "step 9: as # fK as ts rs , bs # fK bs us vs"; |
|
1859 fun prove_fresh_result t (a as Free (_, aT)) = |
|
1860 Goal.prove context'' [] [] |
|
1861 (HOLogic.mk_Trueprop (Const ("Nominal.fresh", |
|
1862 aT --> rT --> HOLogic.boolT) $ a $ t)) |
|
1863 (fn _ => EVERY |
|
1864 [resolve_tac fcbs 1, |
|
1865 REPEAT_DETERM (resolve_tac |
|
1866 (fresh_prems @ rec_freshs1 @ rec_freshs2) 1), |
|
1867 resolve_tac P_ind_ths 1, |
|
1868 REPEAT_DETERM (resolve_tac (P_ths @ rec_prems) 1)]); |
|
1869 |
|
1870 val fresh_results = |
|
1871 map (prove_fresh_result rhs') (List.concat (map fst cargsl')) @ |
|
1872 map (prove_fresh_result lhs') (List.concat (map fst cargsr')); |
|
1873 |
|
1874 (** cs # fK as ts rs , cs # fK bs us vs **) |
|
1875 val _ = warning "step 10: cs # fK as ts rs , cs # fK bs us vs"; |
|
1876 fun prove_fresh_result' recs t (a as Free (_, aT)) = |
|
1877 Goal.prove context'' [] [] |
|
1878 (HOLogic.mk_Trueprop (Const ("Nominal.fresh", |
|
1879 aT --> rT --> HOLogic.boolT) $ a $ t)) |
|
1880 (fn _ => EVERY |
|
1881 [cut_facts_tac recs 1, |
|
1882 REPEAT_DETERM (dresolve_tac |
|
1883 (the (AList.lookup op = rec_fin_supp_thms' aT)) 1), |
|
1884 NominalPermeq.fresh_guess_tac |
|
1885 (HOL_ss addsimps (freshs2 @ |
|
1886 fs_atoms @ fresh_atm @ |
|
1887 List.concat (map snd finite_thss))) 1]); |
|
1888 |
|
1889 val fresh_results' = |
|
1890 map (prove_fresh_result' rec_prems1 rhs') freshs1 @ |
|
1891 map (prove_fresh_result' rec_prems2 lhs') freshs1; |
|
1892 |
|
1893 (** pi1 o (fK as ts rs) = pi2 o (fK bs us vs) **) |
|
1894 val _ = warning "step 11: pi1 o (fK as ts rs) = pi2 o (fK bs us vs)"; |
|
1895 val pi1_pi2_result = Goal.prove context'' [] [] |
|
1896 (HOLogic.mk_Trueprop (HOLogic.mk_eq |
|
1897 (foldr (mk_perm []) rhs' pi1, foldr (mk_perm []) lhs' pi2))) |
|
1898 (fn _ => NominalPermeq.perm_simp_tac (HOL_ss addsimps |
|
1899 pi1_pi2_eqs @ rec_eqns1) 1 THEN |
|
1900 TRY (simp_tac (HOL_ss addsimps |
|
1901 (fresh_prems' @ freshs2' @ calc_atm @ perm_fresh_fresh)) 1)); |
|
1902 |
|
1903 val _ = warning "final result"; |
|
1904 val final = Goal.prove context'' [] [] (term_of concl) |
|
1905 (fn _ => cut_facts_tac [pi1_pi2_result RS sym] 1 THEN |
|
1906 full_simp_tac (HOL_basic_ss addsimps perm_fresh_fresh @ |
|
1907 fresh_results @ fresh_results') 1); |
|
1908 val final' = ProofContext.export context'' context' [final]; |
|
1909 val _ = warning "finished!" |
|
1910 in |
|
1911 resolve_tac final' 1 |
|
1912 end) context 1) (filter_out null (List.concat (map snd ndescr)))) |
1562 end))); |
1913 end))); |
1563 |
1914 |
1564 (* FIXME: theorems are stored in database for testing only *) |
1915 (* FIXME: theorems are stored in database for testing only *) |
1565 val (_, thy12) = thy11 |> |
1916 val (_, thy12) = thy11 |> |
1566 Theory.add_path big_name |> |
1917 Theory.add_path big_name |> |
1567 PureThy.add_thmss |
1918 PureThy.add_thmss |
1568 [(("rec_equiv", List.concat rec_equiv_thms), []), |
1919 [(("rec_equiv", List.concat rec_equiv_thms), []), |
1569 (("rec_equiv'", List.concat rec_equiv_thms'), []), |
1920 (("rec_equiv'", List.concat rec_equiv_thms'), []), |
1570 (("rec_fin_supp", List.concat rec_fin_supp_thms), []), |
1921 (("rec_fin_supp", List.concat rec_fin_supp_thms), []), |
|
1922 (("rec_fresh", List.concat rec_fresh_thms), []), |
1571 (("rec_unique", rec_unique), [])] ||> |
1923 (("rec_unique", rec_unique), [])] ||> |
1572 Theory.parent_path; |
1924 Theory.parent_path; |
1573 |
1925 |
1574 in |
1926 in |
1575 thy12 |
1927 thy12 |