src/Pure/thm.ML
changeset 4820 8f6dbbd8d497
parent 4785 52fa5258db2e
child 4847 ea7d7a65e4e9
equal deleted inserted replaced
4819:ef2e8e2a10e1 4820:8f6dbbd8d497
  1477 
  1477 
  1478 (** meta simp sets **)
  1478 (** meta simp sets **)
  1479 
  1479 
  1480 (* basic components *)
  1480 (* basic components *)
  1481 
  1481 
  1482 type rrule = {thm: thm, lhs: term, perm: bool};
  1482 type rrule = {thm: thm, lhs: term, elhs: term, fo: bool, perm: bool};
  1483 type cong = {thm: thm, lhs: term};
  1483 type cong = {thm: thm, lhs: term};
  1484 type simproc =
  1484 type simproc =
  1485  {name: string, proc: Sign.sg -> thm list -> term -> thm option, lhs: cterm, id: stamp};
  1485  {name: string, proc: Sign.sg -> thm list -> term -> thm option, lhs: cterm, id: stamp};
  1486 
  1486 
  1487 fun eq_rrule ({thm = Thm {prop = p1, ...}, ...}: rrule,
  1487 fun eq_rrule ({thm = Thm {prop = p1, ...}, ...}: rrule,
  1568         generic_merge eq_prem I I prems1 prems2,
  1568         generic_merge eq_prem I I prems1 prems2,
  1569         mk_rews, termless);
  1569         mk_rews, termless);
  1570 
  1570 
  1571 (* add_simps *)
  1571 (* add_simps *)
  1572 
  1572 
       
  1573 fun mk_rrule2{thm,lhs,perm} =
       
  1574   let val elhs = Pattern.eta_contract lhs
       
  1575       val fo = Pattern.first_order elhs orelse not(Pattern.pattern elhs)
       
  1576   in {thm=thm,lhs=lhs,elhs=elhs,fo=fo,perm=perm} end
       
  1577 
  1573 fun insert_rrule(mss as Mss {rules,...},
  1578 fun insert_rrule(mss as Mss {rules,...},
  1574                  rrule as {thm = thm, lhs = lhs, perm = perm}) =
  1579                  rrule as {thm,lhs,perm}) =
  1575   (trace_thm false "Adding rewrite rule:" thm;
  1580   (trace_thm false "Adding rewrite rule:" thm;
  1576    let val rules' = Net.insert_term ((lhs, rrule), rules, eq_rrule)
  1581    let val rrule2 as {elhs,...} = mk_rrule2 rrule
       
  1582        val rules' = Net.insert_term ((elhs, rrule2), rules, eq_rrule)
  1577    in upd_rules(mss,rules') end
  1583    in upd_rules(mss,rules') end
  1578    handle Net.INSERT =>
  1584    handle Net.INSERT =>
  1579      (prthm true "Ignoring duplicate rewrite rule:" thm; mss));
  1585      (prthm true "Ignoring duplicate rewrite rule:" thm; mss));
  1580 
  1586 
  1581 fun vperm (Var _, Var _) = true
  1587 fun vperm (Var _, Var _) = true
  1658           then if reorient sign prems rhs lhs
  1664           then if reorient sign prems rhs lhs
  1659                then mk_eq_True mss thm
  1665                then mk_eq_True mss thm
  1660                else let val Mss{mk_rews={mk_sym,...},...} = mss
  1666                else let val Mss{mk_rews={mk_sym,...},...} = mss
  1661                     in case mk_sym thm of
  1667                     in case mk_sym thm of
  1662                          None => []
  1668                          None => []
  1663                        | Some thm' => rrule_eq_True(thm',rhs,lhs,mss,thm)
  1669                        | Some thm' =>
       
  1670                            let val (_,_,lhs',rhs',_) = decomp_simp thm'
       
  1671                            in rrule_eq_True(thm',lhs',rhs',mss,thm) end
  1664                     end
  1672                     end
  1665           else rrule_eq_True(thm,lhs,rhs,mss,thm)
  1673           else rrule_eq_True(thm,lhs,rhs,mss,thm)
  1666   end;
  1674   end;
  1667 
  1675 
  1668 fun extract_rews(Mss{mk_rews = {mk,...},...},thms) = flat(map mk thms);
  1676 fun extract_rews(Mss{mk_rews = {mk,...},...},thms) = flat(map mk thms);
  1686   foldl insert_rrule (mss, extract_safe_rrules(mss,thm))
  1694   foldl insert_rrule (mss, extract_safe_rrules(mss,thm))
  1687 
  1695 
  1688 (* del_simps *)
  1696 (* del_simps *)
  1689 
  1697 
  1690 fun del_rrule(mss as Mss {rules,...},
  1698 fun del_rrule(mss as Mss {rules,...},
  1691               rrule as {thm = thm, lhs = lhs, perm = perm}) =
  1699               rrule as {thm, elhs, ...}) =
  1692   (upd_rules(mss, Net.delete_term ((lhs, rrule), rules, eq_rrule))
  1700   (upd_rules(mss, Net.delete_term ((elhs, rrule), rules, eq_rrule))
  1693    handle Net.DELETE =>
  1701    handle Net.DELETE =>
  1694      (prthm true "Rewrite rule not in simpset:" thm; mss));
  1702      (prthm true "Rewrite rule not in simpset:" thm; mss));
  1695 
  1703 
  1696 fun del_simps(mss,thms) =
  1704 fun del_simps(mss,thms) =
  1697   orient_comb_simps del_rrule (mk_rrule mss) (mss,thms);
  1705   orient_comb_simps del_rrule (map mk_rrule2 o mk_rrule mss) (mss,thms);
  1698 
  1706 
  1699 
  1707 
  1700 (* add_congs *)
  1708 (* add_congs *)
  1701 
  1709 
  1702 fun add_cong (Mss {rules,congs,procs,bounds,prems,mk_rews,termless}, thm) =
  1710 fun add_cong (Mss {rules,congs,procs,bounds,prems,mk_rews,termless}, thm) =
  1832             Abs(case assoc_string(ren,x) of None => x | Some(y) => y, T, renAbs(b))
  1840             Abs(case assoc_string(ren,x) of None => x | Some(y) => y, T, renAbs(b))
  1833         | renAbs(f$t) = renAbs(f) $ renAbs(t)
  1841         | renAbs(f$t) = renAbs(f) $ renAbs(t)
  1834         | renAbs(t) = t
  1842         | renAbs(t) = t
  1835   in subst_vars insts (if null(ren) then prop else renAbs(prop)) end;
  1843   in subst_vars insts (if null(ren) then prop else renAbs(prop)) end;
  1836 
  1844 
       
  1845 fun incr_insts i (in1:(indexname*typ)list,in2:(indexname*term)list) =
       
  1846   let fun incr ((a,n),x) = ((a,n+i),x)
       
  1847   in (map incr in1, map incr in2) end;
       
  1848 
  1837 fun add_insts_sorts ((iTs, is), Ss) =
  1849 fun add_insts_sorts ((iTs, is), Ss) =
  1838   add_typs_sorts (map snd iTs, add_terms_sorts (map snd is, Ss));
  1850   add_typs_sorts (map snd iTs, add_terms_sorts (map snd is, Ss));
  1839 
  1851 
  1840 
  1852 
  1841 (* mk_procrule *)
  1853 (* mk_procrule *)
  1842 
  1854 
  1843 fun mk_procrule thm =
  1855 fun mk_procrule thm =
  1844   let val (_,prems,lhs,rhs,_) = decomp_simp thm
  1856   let val (_,prems,lhs,rhs,_) = decomp_simp thm
  1845   in if rewrite_rule_extra_vars prems lhs rhs
  1857   in if rewrite_rule_extra_vars prems lhs rhs
  1846      then (prthm true "Extra vars on rhs:" thm; [])
  1858      then (prthm true "Extra vars on rhs:" thm; [])
  1847      else [{thm = thm, lhs = lhs, perm = false}]
  1859      else [mk_rrule2{thm = thm, lhs = lhs, perm = false}]
  1848   end;
  1860   end;
  1849 
  1861 
  1850 
  1862 
  1851 (* conversion to apply the meta simpset to a term *)
  1863 (* conversion to apply the meta simpset to a term *)
  1852 
  1864 
  1865              (mss as Mss{rules, procs, termless, prems, ...}) 
  1877              (mss as Mss{rules, procs, termless, prems, ...}) 
  1866              (t:term,etc as (shypst,hypst,ders)) =
  1878              (t:term,etc as (shypst,hypst,ders)) =
  1867   let
  1879   let
  1868     val signt = Sign.deref sign_reft;
  1880     val signt = Sign.deref sign_reft;
  1869     val tsigt = Sign.tsig_of signt;
  1881     val tsigt = Sign.tsig_of signt;
  1870     fun rew{thm as Thm{sign_ref,der,shyps,hyps,prop,maxidx,...}, lhs, perm} =
  1882     fun rew{thm as Thm{sign_ref,der,shyps,hyps,prop,maxidx,...},
       
  1883             lhs, elhs, fo, perm} =
  1871       let
  1884       let
  1872         val _ = if Sign.subsig (Sign.deref sign_ref, signt) then ()
  1885         val _ = if Sign.subsig (Sign.deref sign_ref, signt) then ()
  1873                 else (trace_thm true "Rewrite rule from different theory:" thm;
  1886                 else (trace_thm true "Rewrite rule from different theory:" thm;
  1874                       raise Pattern.MATCH);
  1887                       raise Pattern.MATCH);
  1875         val rprop = if maxt = ~1 then prop
  1888         val rprop = if maxt = ~1 then prop
  1876                     else Logic.incr_indexes([],maxt+1) prop;
  1889                     else Logic.incr_indexes([],maxt+1) prop;
  1877         val rlhs = if maxt = ~1 then lhs
  1890         val insts = if fo then Pattern.first_order_match tsigt (elhs,t)
  1878                    else fst(Logic.dest_equals(Logic.strip_imp_concl rprop))
  1891                           else Pattern.match             tsigt (elhs,t);
  1879         val insts = Pattern.match tsigt (rlhs,t);
  1892         val insts = if maxt = ~1 then insts else incr_insts (maxt+1) insts
  1880         val prop' = ren_inst(insts,rprop,rlhs,t);
  1893         val prop' = ren_inst(insts,rprop,lhs,t);
  1881         val hyps' = union_term(hyps,hypst);
  1894         val hyps' = union_term(hyps,hypst);
  1882         val shyps' = add_insts_sorts (insts, union_sort(shyps,shypst));
  1895         val shyps' = add_insts_sorts (insts, union_sort(shyps,shypst));
  1883         val unconditional = (Logic.count_prems(prop',0) = 0);
  1896         val unconditional = (Logic.count_prems(prop',0) = 0);
  1884         val maxidx' = if unconditional then maxt else maxidx+maxt+1
  1897         val maxidx' = if unconditional then maxt else maxidx+maxt+1
  1885         val ct' = Cterm{sign_ref = sign_reft,       (*used for deriv only*)
  1898         val ct' = Cterm{sign_ref = sign_reft,       (*used for deriv only*)
  1904       | rews (rrule :: rrules) =
  1917       | rews (rrule :: rrules) =
  1905           let val opt = rew rrule handle Pattern.MATCH => None
  1918           let val opt = rew rrule handle Pattern.MATCH => None
  1906           in case opt of None => rews rrules | some => some end;
  1919           in case opt of None => rews rrules | some => some end;
  1907 
  1920 
  1908     fun sort_rrules rrs = let
  1921     fun sort_rrules rrs = let
  1909       fun is_simple {thm as Thm{prop,...}, lhs, perm} = case prop of 
  1922       fun is_simple({thm as Thm{prop,...}, ...}:rrule) = case prop of 
  1910                                       Const("==",_) $ _ $ _ => true
  1923                                       Const("==",_) $ _ $ _ => true
  1911                                       | _                   => false 
  1924                                       | _                   => false 
  1912       fun sort []        (re1,re2) = re1 @ re2
  1925       fun sort []        (re1,re2) = re1 @ re2
  1913         | sort (rr::rrs) (re1,re2) = if is_simple rr 
  1926         | sort (rr::rrs) (re1,re2) = if is_simple rr 
  1914                                      then sort rrs (rr::re1,re2)
  1927                                      then sort rrs (rr::re1,re2)
  1926                   (case rews (mk_procrule raw_thm) of
  1939                   (case rews (mk_procrule raw_thm) of
  1927                     None => (trace false "IGNORED"; proc_rews eta_t ps)
  1940                     None => (trace false "IGNORED"; proc_rews eta_t ps)
  1928                   | some => some)))
  1941                   | some => some)))
  1929           else proc_rews eta_t ps;
  1942           else proc_rews eta_t ps;
  1930   in case t of
  1943   in case t of
  1931        Abs (_, _, body) $ u =>
  1944        Abs (_, _, body) $ u => Some (subst_bound (u, body), etc)
  1932          Some (subst_bound (u, body), etc)
       
  1933      | _ => (case rews (sort_rrules (Net.match_term rules t)) of
  1945      | _ => (case rews (sort_rrules (Net.match_term rules t)) of
  1934                None => proc_rews (Pattern.eta_contract t)
  1946                None => proc_rews (Pattern.eta_contract t)
  1935                                  (Net.match_term procs t)
  1947                                  (Net.match_term procs t)
  1936              | some => some)
  1948              | some => some)
  1937   end;
  1949   end;
  2043       let val (prem1,etc1) = try_botc mss (prem,etc)
  2055       let val (prem1,etc1) = try_botc mss (prem,etc)
  2044       in mut_impc1(prems, prem1, conc, mss, etc1) end
  2056       in mut_impc1(prems, prem1, conc, mss, etc1) end
  2045 
  2057 
  2046     and mut_impc1(prems, prem1, conc, mss, etc1 as (_,hyps1,_)) =
  2058     and mut_impc1(prems, prem1, conc, mss, etc1 as (_,hyps1,_)) =
  2047       let
  2059       let
  2048         fun uncond({thm,lhs,...}:rrule) =
  2060         fun uncond({thm,lhs,perm}) =
  2049           if nprems_of thm = 0 then Some lhs else None
  2061           if nprems_of thm = 0 then Some lhs else None
  2050 
  2062 
  2051         val (lhss1,mss1) =
  2063         val (lhss1,mss1) =
  2052           if maxidx_of_term prem1 <> ~1
  2064           if maxidx_of_term prem1 <> ~1
  2053           then (trace_term true "Cannot add premise as rewrite rule because it contains (type) unknowns:"
  2065           then (trace_term true "Cannot add premise as rewrite rule because it contains (type) unknowns:"