98 fun remove_suc thy thms = |
98 fun remove_suc thy thms = |
99 let |
99 let |
100 val Suc_if_eq' = Thm.transfer thy Suc_if_eq; |
100 val Suc_if_eq' = Thm.transfer thy Suc_if_eq; |
101 val ctzero = cterm_of (sign_of Main.thy) HOLogic.zero; |
101 val ctzero = cterm_of (sign_of Main.thy) HOLogic.zero; |
102 val vname = variant (map fst |
102 val vname = variant (map fst |
103 (foldl add_term_varnames ([], map prop_of thms))) "x"; |
103 (Library.foldl add_term_varnames ([], map prop_of thms))) "x"; |
104 val cv = cterm_of (sign_of Main.thy) (Var ((vname, 0), HOLogic.natT)); |
104 val cv = cterm_of (sign_of Main.thy) (Var ((vname, 0), HOLogic.natT)); |
105 fun lhs_of th = snd (Thm.dest_comb |
105 fun lhs_of th = snd (Thm.dest_comb |
106 (fst (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th)))))); |
106 (fst (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th)))))); |
107 fun rhs_of th = snd (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th)))); |
107 fun rhs_of th = snd (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th)))); |
108 fun find_vars ct = (case term_of ct of |
108 fun find_vars ct = (case term_of ct of |
112 in |
112 in |
113 map (apfst (pairself (fn ct => Thm.capply ct ct2))) (find_vars ct1) @ |
113 map (apfst (pairself (fn ct => Thm.capply ct ct2))) (find_vars ct1) @ |
114 map (apfst (pairself (Thm.capply ct1))) (find_vars ct2) |
114 map (apfst (pairself (Thm.capply ct1))) (find_vars ct2) |
115 end |
115 end |
116 | _ => []); |
116 | _ => []); |
117 val eqs1 = flat (map |
117 val eqs1 = List.concat (map |
118 (fn th => map (pair th) (find_vars (lhs_of th))) thms); |
118 (fn th => map (pair th) (find_vars (lhs_of th))) thms); |
119 val eqs2 = map (fn x as (_, ((_, ctzero), _)) => (x, mapfilter (fn th => |
119 val eqs2 = map (fn x as (_, ((_, ctzero), _)) => (x, List.mapPartial (fn th => |
120 SOME (th, Thm.cterm_match (lhs_of th, ctzero)) |
120 SOME (th, Thm.cterm_match (lhs_of th, ctzero)) |
121 handle Pattern.MATCH => NONE) thms)) eqs1; |
121 handle Pattern.MATCH => NONE) thms)) eqs1; |
122 fun distinct_vars vs = forall is_Var vs andalso null (duplicates vs); |
122 fun distinct_vars vs = forall is_Var vs andalso null (duplicates vs); |
123 val eqs2' = map (apsnd (filter (fn (_, (_, s)) => |
123 val eqs2' = map (apsnd (List.filter (fn (_, (_, s)) => |
124 distinct_vars (map (term_of o snd) s)))) eqs2; |
124 distinct_vars (map (term_of o snd) s)))) eqs2; |
125 fun mk_thms b ((th, ((ct, _), cv')), (th', s) :: _) = |
125 fun mk_thms b ((th, ((ct, _), cv')), (th', s) :: _) = |
126 let |
126 let |
127 val th'' = Thm.instantiate s th'; |
127 val th'' = Thm.instantiate s th'; |
128 val th''' = |
128 val th''' = |
131 (Drule.instantiate' |
131 (Drule.instantiate' |
132 [SOME (ctyp_of_term ct)] [SOME (Thm.cabs cv ct), |
132 [SOME (ctyp_of_term ct)] [SOME (Thm.cabs cv ct), |
133 SOME (rhs_of th''), SOME (Thm.cabs cv' (rhs_of th)), SOME cv'] |
133 SOME (rhs_of th''), SOME (Thm.cabs cv' (rhs_of th)), SOME cv'] |
134 Suc_if_eq')) th'') (Thm.forall_intr cv' th) |
134 Suc_if_eq')) th'') (Thm.forall_intr cv' th) |
135 in |
135 in |
136 mapfilter (fn thm => |
136 List.mapPartial (fn thm => |
137 if thm = th then SOME th''' |
137 if thm = th then SOME th''' |
138 else if b andalso thm = th' then NONE |
138 else if b andalso thm = th' then NONE |
139 else SOME thm) thms |
139 else SOME thm) thms |
140 end |
140 end |
141 in |
141 in |
158 |
158 |
159 fun remove_suc_clause thy thms = |
159 fun remove_suc_clause thy thms = |
160 let |
160 let |
161 val Suc_clause' = Thm.transfer thy Suc_clause; |
161 val Suc_clause' = Thm.transfer thy Suc_clause; |
162 val vname = variant (map fst |
162 val vname = variant (map fst |
163 (foldl add_term_varnames ([], map prop_of thms))) "x"; |
163 (Library.foldl add_term_varnames ([], map prop_of thms))) "x"; |
164 fun find_var (t as Const ("Suc", _) $ (v as Var _)) = SOME (t, v) |
164 fun find_var (t as Const ("Suc", _) $ (v as Var _)) = SOME (t, v) |
165 | find_var (t $ u) = (case find_var t of NONE => find_var u | x => x) |
165 | find_var (t $ u) = (case find_var t of NONE => find_var u | x => x) |
166 | find_var _ = NONE; |
166 | find_var _ = NONE; |
167 fun find_thm th = |
167 fun find_thm th = |
168 let val th' = ObjectLogic.atomize_thm th |
168 let val th' = ObjectLogic.atomize_thm th |
169 in apsome (pair (th, th')) (find_var (prop_of th')) end |
169 in Option.map (pair (th, th')) (find_var (prop_of th')) end |
170 in |
170 in |
171 case get_first find_thm thms of |
171 case get_first find_thm thms of |
172 NONE => thms |
172 NONE => thms |
173 | SOME ((th, th'), (Sucv, v)) => |
173 | SOME ((th, th'), (Sucv, v)) => |
174 let |
174 let |
189 |
189 |
190 fun clause_suc_preproc thy ths = |
190 fun clause_suc_preproc thy ths = |
191 let val dest = fst o HOLogic.dest_mem o HOLogic.dest_Trueprop |
191 let val dest = fst o HOLogic.dest_mem o HOLogic.dest_Trueprop |
192 in |
192 in |
193 if forall (can (dest o concl_of)) ths andalso |
193 if forall (can (dest o concl_of)) ths andalso |
194 exists (fn th => "Suc" mem foldr add_term_consts |
194 exists (fn th => "Suc" mem Library.foldr add_term_consts |
195 (mapfilter (try dest) (concl_of th :: prems_of th), [])) ths |
195 (List.mapPartial (try dest) (concl_of th :: prems_of th), [])) ths |
196 then remove_suc_clause thy ths else ths |
196 then remove_suc_clause thy ths else ths |
197 end; |
197 end; |
198 |
198 |
199 val suc_preproc_setup = |
199 val suc_preproc_setup = |
200 [Codegen.add_preprocessor eqn_suc_preproc, |
200 [Codegen.add_preprocessor eqn_suc_preproc, |