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 |