src/Pure/thm.ML
changeset 5624 4813dd0fe6e5
parent 5623 75b513db9a3a
child 6089 4d2d5556b4f9
equal deleted inserted replaced
5623:75b513db9a3a 5624:4813dd0fe6e5
  1508 
  1508 
  1509 (*
  1509 (*
  1510   A "mss" contains data needed during conversion:
  1510   A "mss" contains data needed during conversion:
  1511     rules: discrimination net of rewrite rules;
  1511     rules: discrimination net of rewrite rules;
  1512     congs: association list of congruence rules and
  1512     congs: association list of congruence rules and
  1513            a flag iff all of the congruences are 'full'.
  1513            a list of `weak' congruence constants.
  1514           A congruence is 'full' if it enforces normalization of all arguments.
  1514            A congruence is `weak' if it avoids normalization of some argument.
  1515     procs: discrimination net of simplification procedures
  1515     procs: discrimination net of simplification procedures
  1516       (functions that prove rewrite rules on the fly);
  1516       (functions that prove rewrite rules on the fly);
  1517     bounds: names of bound variables already used
  1517     bounds: names of bound variables already used
  1518       (for generating new names when rewriting under lambda abstractions);
  1518       (for generating new names when rewriting under lambda abstractions);
  1519     prems: current premises;
  1519     prems: current premises;
  1524 *)
  1524 *)
  1525 
  1525 
  1526 datatype meta_simpset =
  1526 datatype meta_simpset =
  1527   Mss of {
  1527   Mss of {
  1528     rules: rrule Net.net,
  1528     rules: rrule Net.net,
  1529     congs: (string * cong) list * bool,
  1529     congs: (string * cong) list * string list,
  1530     procs: simproc Net.net,
  1530     procs: simproc Net.net,
  1531     bounds: string list,
  1531     bounds: string list,
  1532     prems: thm list,
  1532     prems: thm list,
  1533     mk_rews: {mk: thm -> thm list,
  1533     mk_rews: {mk: thm -> thm list,
  1534               mk_sym: thm -> thm option,
  1534               mk_sym: thm -> thm option,
  1542 fun upd_rules(Mss{rules,congs,procs,bounds,prems,mk_rews,termless}, rules') =
  1542 fun upd_rules(Mss{rules,congs,procs,bounds,prems,mk_rews,termless}, rules') =
  1543   mk_mss(rules',congs,procs,bounds,prems,mk_rews,termless);
  1543   mk_mss(rules',congs,procs,bounds,prems,mk_rews,termless);
  1544 
  1544 
  1545 val empty_mss =
  1545 val empty_mss =
  1546   let val mk_rews = {mk = K [], mk_sym = K None, mk_eq_True = K None}
  1546   let val mk_rews = {mk = K [], mk_sym = K None, mk_eq_True = K None}
  1547   in mk_mss (Net.empty, ([],true), Net.empty, [], [], mk_rews, Term.termless)
  1547   in mk_mss (Net.empty, ([],[]), Net.empty, [], [], mk_rews, Term.termless)
  1548   end;
  1548   end;
  1549 
  1549 
  1550 
  1550 
  1551 
  1551 
  1552 (** simpset operations **)
  1552 (** simpset operations **)
  1563 
  1563 
  1564 
  1564 
  1565 (* merge_mss *)		(*NOTE: ignores mk_rews and termless of 2nd mss*)
  1565 (* merge_mss *)		(*NOTE: ignores mk_rews and termless of 2nd mss*)
  1566 
  1566 
  1567 fun merge_mss
  1567 fun merge_mss
  1568  (Mss {rules = rules1, congs = (congs1,full1), procs = procs1,
  1568  (Mss {rules = rules1, congs = (congs1,weak1), procs = procs1,
  1569        bounds = bounds1, prems = prems1, mk_rews, termless},
  1569        bounds = bounds1, prems = prems1, mk_rews, termless},
  1570   Mss {rules = rules2, congs = (congs2,full2), procs = procs2,
  1570   Mss {rules = rules2, congs = (congs2,weak2), procs = procs2,
  1571        bounds = bounds2, prems = prems2, ...}) =
  1571        bounds = bounds2, prems = prems2, ...}) =
  1572       mk_mss
  1572       mk_mss
  1573        (Net.merge (rules1, rules2, eq_rrule),
  1573        (Net.merge (rules1, rules2, eq_rrule),
  1574         (generic_merge (eq_cong o pairself snd) I I congs1 congs2,
  1574         (generic_merge (eq_cong o pairself snd) I I congs1 congs2,
  1575          full1 andalso full2),
  1575         merge_lists weak1 weak2),
  1576         Net.merge (procs1, procs2, eq_simproc),
  1576         Net.merge (procs1, procs2, eq_simproc),
  1577         merge_lists bounds1 bounds2,
  1577         merge_lists bounds1 bounds2,
  1578         generic_merge eq_prem I I prems1 prems2,
  1578         generic_merge eq_prem I I prems1 prems2,
  1579         mk_rews, termless);
  1579         mk_rews, termless);
  1580 
  1580 
  1749     val (lhs, _) = Logic.dest_equals (concl_of thm) handle TERM _ =>
  1749     val (lhs, _) = Logic.dest_equals (concl_of thm) handle TERM _ =>
  1750       raise SIMPLIFIER ("Congruence not a meta-equality", thm);
  1750       raise SIMPLIFIER ("Congruence not a meta-equality", thm);
  1751 (*   val lhs = Pattern.eta_contract lhs; *)
  1751 (*   val lhs = Pattern.eta_contract lhs; *)
  1752     val (a, _) = dest_Const (head_of lhs) handle TERM _ =>
  1752     val (a, _) = dest_Const (head_of lhs) handle TERM _ =>
  1753       raise SIMPLIFIER ("Congruence must start with a constant", thm);
  1753       raise SIMPLIFIER ("Congruence must start with a constant", thm);
  1754     val (alist,full) = congs
  1754     val (alist,weak) = congs
  1755     val full2 = full andalso is_full_cong thm
  1755     val weak2 = if is_full_cong thm then weak else a::weak
  1756   in
  1756   in
  1757     mk_mss (rules, ((a, {lhs = lhs, thm = thm}) :: alist, full2),
  1757     mk_mss (rules, ((a, {lhs = lhs, thm = thm}) :: alist, weak2),
  1758             procs, bounds, prems, mk_rews, termless)
  1758             procs, bounds, prems, mk_rews, termless)
  1759   end;
  1759   end;
  1760 
  1760 
  1761 val (op add_congs) = foldl add_cong;
  1761 val (op add_congs) = foldl add_cong;
  1762 
  1762 
  1768     val (lhs, _) = Logic.dest_equals (concl_of thm) handle TERM _ =>
  1768     val (lhs, _) = Logic.dest_equals (concl_of thm) handle TERM _ =>
  1769       raise SIMPLIFIER ("Congruence not a meta-equality", thm);
  1769       raise SIMPLIFIER ("Congruence not a meta-equality", thm);
  1770 (*   val lhs = Pattern.eta_contract lhs; *)
  1770 (*   val lhs = Pattern.eta_contract lhs; *)
  1771     val (a, _) = dest_Const (head_of lhs) handle TERM _ =>
  1771     val (a, _) = dest_Const (head_of lhs) handle TERM _ =>
  1772       raise SIMPLIFIER ("Congruence must start with a constant", thm);
  1772       raise SIMPLIFIER ("Congruence must start with a constant", thm);
  1773     val (alist,full) = congs
  1773     val (alist,_) = congs
  1774     val alist2 = filter (fn (x,_)=> x<>a) alist
  1774     val alist2 = filter (fn (x,_)=> x<>a) alist
  1775     val full2 = forall (fn(_,{thm,...}) => is_full_cong thm) alist2
  1775     val weak2 = mapfilter (fn(a,{thm,...}) => if is_full_cong thm then None
       
  1776                                               else Some a)
       
  1777                    alist2
  1776   in
  1778   in
  1777     mk_mss (rules, (alist2,full2), procs, bounds, prems, mk_rews, termless)
  1779     mk_mss (rules, (alist2,weak2), procs, bounds, prems, mk_rews, termless)
  1778   end;
  1780   end;
  1779 
  1781 
  1780 val (op del_congs) = foldl del_cong;
  1782 val (op del_congs) = foldl del_cong;
  1781 
  1783 
  1782 
  1784 
  1915    with the term. Once a Var is encountered, the corresponding term is
  1917    with the term. Once a Var is encountered, the corresponding term is
  1916    already in normal form.
  1918    already in normal form.
  1917    skel0 is a dummy skeleton that is to enforce complete normalization.
  1919    skel0 is a dummy skeleton that is to enforce complete normalization.
  1918 *)
  1920 *)
  1919 val skel0 = Bound 0;
  1921 val skel0 = Bound 0;
       
  1922 
       
  1923 (* Use rhs as skeleton only if the lhs does not contain unnormalized bits.
       
  1924    The latter may happen iff there are weak congruence rules for constants
       
  1925    in the lhs.
       
  1926 *)
       
  1927 fun uncond_skel((_,weak),(lhs,rhs)) =
       
  1928   if null weak then rhs (* optimization *)
       
  1929   else if exists_Const (fn (c,_) => c mem weak) lhs then skel0
       
  1930        else rhs;
       
  1931 
       
  1932 (* Behaves like unconditional rule if rhs does not contain vars not in the lhs.
       
  1933    Otherwise those vars may become instantiated with unnormalized terms
       
  1934    while the premises are solved.
       
  1935 *)
       
  1936 fun cond_skel(args as (congs,(lhs,rhs))) =
       
  1937   if term_vars rhs subset term_vars lhs then uncond_skel(args)
       
  1938   else skel0;
  1920 
  1939 
  1921 (*
  1940 (*
  1922   we try in order:
  1941   we try in order:
  1923     (1) beta reduction
  1942     (1) beta reduction
  1924     (2) unconditional rewrite rules
  1943     (2) unconditional rewrite rules
  1957         val thm' = Thm{sign_ref = sign_reft, der = der', shyps = shyps',
  1976         val thm' = Thm{sign_ref = sign_reft, der = der', shyps = shyps',
  1958                        hyps = hyps', prop = prop', maxidx = maxidx'}
  1977                        hyps = hyps', prop = prop', maxidx = maxidx'}
  1959         val (lhs',rhs') = Logic.dest_equals(Logic.strip_imp_concl prop')
  1978         val (lhs',rhs') = Logic.dest_equals(Logic.strip_imp_concl prop')
  1960       in
  1979       in
  1961         if perm andalso not(termless(rhs',lhs')) then None
  1980         if perm andalso not(termless(rhs',lhs')) then None
  1962         else (trace_thm false "Applying instance of rewrite rule:" thm;
  1981         else
  1963               if unconditional
  1982           (trace_thm false "Applying instance of rewrite rule:" thm;
  1964               then (trace_thm false "Rewriting:" thm';
  1983            if unconditional
  1965                     let val (_,rhs) = Logic.dest_equals prop
  1984            then
  1966                     in Some((rhs', (shyps', hyps', der'::ders)),
  1985              (trace_thm false "Rewriting:" thm';
  1967                             if snd congs then rhs else skel0)
  1986               let val lr = Logic.dest_equals prop
  1968                         (* use rhs as depth-limit only if all congs are full *)
  1987                   val trec' = (rhs', (shyps', hyps', der'::ders))
  1969                     end)
  1988               in Some(trec',uncond_skel(congs,lr)) end)
  1970               else (trace_thm false "Trying to rewrite:" thm';
  1989            else
  1971                     case prover mss thm' of
  1990              (trace_thm false "Trying to rewrite:" thm';
  1972                       None       => (trace_thm false "FAILED" thm'; None)
  1991               case prover mss thm' of
  1973                     | Some(thm2) =>
  1992                 None       => (trace_thm false "FAILED" thm'; None)
  1974                         (case check_conv(thm2,prop',ders) of
  1993               | Some(thm2) =>
  1975                            None => None | Some trec => Some(trec,skel0))))
  1994                   (case check_conv(thm2,prop',ders) of
       
  1995                      None => None |
       
  1996                      Some trec =>
       
  1997                        let val concl = Logic.strip_imp_concl prop
       
  1998                            val lr = Logic.dest_equals concl
       
  1999                        in Some(trec,cond_skel(congs,lr)) end)))
  1976       end
  2000       end
  1977 
  2001 
  1978     fun rews [] = None
  2002     fun rews [] = None
  1979       | rews (rrule :: rrules) =
  2003       | rews (rrule :: rrules) =
  1980           let val opt = rew rrule handle Pattern.MATCH => None
  2004           let val opt = rew rrule handle Pattern.MATCH => None