121 else if forall (is_intro constname) specs then |
121 else if forall (is_intro constname) specs then |
122 map rewrite_intros specs |
122 map rewrite_intros specs |
123 else |
123 else |
124 error ("unexpected specification for constant " ^ quote constname ^ ":\n" |
124 error ("unexpected specification for constant " ^ quote constname ^ ":\n" |
125 ^ commas (map (quote o Display.string_of_thm_global thy) specs)) |
125 ^ commas (map (quote o Display.string_of_thm_global thy) specs)) |
126 val _ = tracing ("Introduction rules of definitions before flattening: " |
|
127 ^ commas (map (Display.string_of_thm ctxt) intros)) |
|
128 val _ = tracing "Defining local predicates and their intro rules..." |
|
129 val (intros', (local_defs, thy')) = flatten_intros constname intros thy |
126 val (intros', (local_defs, thy')) = flatten_intros constname intros thy |
130 val (intross, thy'') = fold_map preprocess local_defs thy' |
127 val (intross, thy'') = fold_map preprocess local_defs thy' |
131 in |
128 in |
132 (intros' :: flat intross,thy'') |
129 ((constname, intros') :: flat intross,thy'') |
133 end; |
130 end; |
134 |
131 |
135 fun preprocess_term t thy = error "preprocess_pred_term: to implement" |
132 fun preprocess_term t thy = error "preprocess_pred_term: to implement" |
136 |
133 |
137 |
134 fun is_Abs (Abs _) = true |
|
135 | is_Abs _ = false |
|
136 |
|
137 fun flat_higher_order_arguments (intross, thy) = |
|
138 let |
|
139 fun process constname atom (new_defs, thy) = |
|
140 let |
|
141 val (pred, args) = strip_comb atom |
|
142 val abs_args = filter is_Abs args |
|
143 fun replace_abs_arg (abs_arg as Abs _ ) (new_defs, thy) = |
|
144 let |
|
145 val _ = tracing ("Introduce new constant for " ^ |
|
146 Syntax.string_of_term_global thy abs_arg) |
|
147 val vars = map Var (Term.add_vars abs_arg []) |
|
148 val abs_arg' = Logic.unvarify abs_arg |
|
149 val frees = map Free (Term.add_frees abs_arg' []) |
|
150 val constname = Name.variant (map (Long_Name.base_name o fst) new_defs) |
|
151 ((Long_Name.base_name constname) ^ "_hoaux") |
|
152 val full_constname = Sign.full_bname thy constname |
|
153 val constT = map fastype_of frees ---> (fastype_of abs_arg') |
|
154 val const = Const (full_constname, constT) |
|
155 val lhs = list_comb (const, frees) |
|
156 val def = Logic.mk_equals (lhs, abs_arg') |
|
157 val _ = tracing (Syntax.string_of_term_global thy def) |
|
158 val ([definition], thy') = thy |
|
159 |> Sign.add_consts_i [(Binding.name constname, constT, NoSyn)] |
|
160 |> PureThy.add_defs false [((Binding.name (constname ^ "_def"), def), [])] |
|
161 in |
|
162 (list_comb (Logic.varify const, vars), ((full_constname, [definition])::new_defs, thy')) |
|
163 end |
|
164 | replace_abs_arg arg (new_defs, thy) = (arg, (new_defs, thy)) |
|
165 val (args', (new_defs', thy')) = fold_map replace_abs_arg args (new_defs, thy) |
|
166 in |
|
167 (list_comb (pred, args'), (new_defs', thy')) |
|
168 end |
|
169 fun flat_intro intro (new_defs, thy) = |
|
170 let |
|
171 val constname = fst (dest_Const (fst (strip_comb |
|
172 (HOLogic.dest_Trueprop (Logic.strip_imp_concl (prop_of intro)))))) |
|
173 val (intro_ts, (new_defs, thy)) = fold_map_atoms (process constname) (prop_of intro) (new_defs, thy) |
|
174 val th = setmp quick_and_dirty true (SkipProof.make_thm thy) intro_ts |
|
175 in |
|
176 (th, (new_defs, thy)) |
|
177 end |
|
178 fun fold_map_spec f [] s = ([], s) |
|
179 | fold_map_spec f ((c, ths) :: specs) s = |
|
180 let |
|
181 val (ths', s') = f ths s |
|
182 val (specs', s'') = fold_map_spec f specs s' |
|
183 in ((c, ths') :: specs', s'') end |
|
184 val (intross', (new_defs, thy')) = fold_map_spec (fold_map flat_intro) intross ([], thy) |
|
185 in |
|
186 (intross', (new_defs, thy')) |
|
187 end |
|
188 |
138 end; |
189 end; |