feat(library/init/meta/converter): implement conversionals using ext_simplify_core

This commit is contained in:
Leonardo de Moura 2016-10-19 17:23:32 -07:00
parent a4ef8f385d
commit 6edec4c4e9
3 changed files with 55 additions and 39 deletions

View file

@ -172,13 +172,7 @@ meta def match_expr (p : pexpr) : conv unit :=
new_p ← pexpr_to_pattern p,
tactic.match_pattern new_p e >> return ⟨(), e, none⟩
meta def attr : user_attribute :=
{ name := `convsub,
descr := "for marking conversionals (conv unit -> conv unit) used by `conv.sub`" }
run_command attribute.register `conv.attr
@[convsub] meta def funext (c : conv unit) : conv unit :=
meta def funext (c : conv unit) : conv unit :=
λ r lhs, do
guard (r = `eq),
(expr.lam n bi d b) ← return lhs | failed,
@ -219,31 +213,59 @@ meta def congr_core (c_f c_a : conv unit) : conv unit :=
return ⟨(), rhs, some pr⟩
end
@[convsub] meta def congr (c : conv unit) : conv unit :=
meta def congr (c : conv unit) : conv unit :=
congr_core c c
meta def subc_core : list name → conv unit → conv unit
| [] c r e := return ⟨(), e, none⟩
| (n::ns) c r e := do
F ← eval_expr (conv unit → conv unit) (expr.const n []),
(F c r e <|> subc_core ns c r e)
/- Try all conversionals F tagged with attribute @[convsub] -/
meta def subc (c : conv unit) : conv unit :=
meta def bottom_up (c : conv unit) : conv unit :=
λ r e, do
is ← attribute.get_instances `convsub,
subc_core is c r e
s ← simp_lemmas.mk_default,
(a, new_e, pr) ←
ext_simplify_core () default_simplify_config s
(λ u, return u)
(λ a s r p e, failed)
(λ a s r p e, do ⟨u, new_e, pr⟩ ← c r e, return ((), new_e, pr, tt))
r e,
return ⟨(), new_e, some pr⟩
meta def depth_first : conv unit → conv unit
| c := (subc (depth_first c) >> repeat c)
meta def top_down (c : conv unit) : conv unit :=
λ r e, do
s ← simp_lemmas.mk_default,
(a, new_e, pr) ←
ext_simplify_core () default_simplify_config s
(λ u, return u)
(λ a s r p e, do ⟨u, new_e, pr⟩ ← c r e, return ((), new_e, pr, tt))
(λ a s r p e, failed)
r e,
return ⟨(), new_e, some pr⟩
meta def find : conv unit → conv unit
| c := c <|> subc (find c)
meta def find (c : conv unit) : conv unit :=
λ r e, do
s ← simp_lemmas.mk_default,
(a, new_e, pr) ←
ext_simplify_core () default_simplify_config s
(λ u, return u)
(λ a s r p e,
(do ⟨u, new_e, pr⟩ ← c r e, return ((), new_e, pr, ff))
<|>
return ((), e, none, tt))
(λ a s r p e, failed)
r e,
return ⟨(), new_e, some pr⟩
meta def find_pattern : pattern → conv unit → conv unit
| p c := do
matched ← tryb $ match_pattern p,
if matched then c else (subc (find_pattern p c))
meta def find_pattern (pat : pattern) (c : conv unit) : conv unit :=
λ r e, do
s ← simp_lemmas.mk_default,
(a, new_e, pr) ←
ext_simplify_core () default_simplify_config s
(λ u, return u)
(λ a s r p e, do
matched ← (tactic.match_pattern pat e >> return tt) <|> return ff,
if matched
then do ⟨u, new_e, pr⟩ ← c r e, return ((), new_e, pr, ff)
else return ((), e, none, tt))
(λ a s r p e, failed)
r e,
return ⟨(), new_e, some pr⟩
meta def findp : pexpr → conv unit → conv unit :=
λ p c r e, do
@ -261,6 +283,4 @@ do (r, lhs, rhs) ← (target_lhs_rhs <|> fail "conversion failed, target is not
new_lhs_fmt^.indent 4)),
exact pr
/- TODO(Leo): add more primitives and combinators. Example: congruence, etc -/
end conv

View file

@ -185,11 +185,11 @@ meta constant ext_simplify_core
- 'new_e' is a new expression s.t. 'e r new_e'
- 'new_pr' is a proof for 'e r new_e', If it is none, the proof is assumed to be by reflexivity
- 'flag' if tt 'new_e' children should be visited, and 'post' invoked. -/
(pre : A → name → simp_lemmas → option expr → expr → tactic (A × expr × option expr × bool))
(pre : A → simp_lemmas → name → option expr → expr → tactic (A × expr × option expr × bool))
/- (post a r s p e) is invoked after visiting the children of subterm 'e',
The output is similar to (pre a r s p e), but the 'flag' indicates whether
the new expression should be revisited or not. -/
(post : A → name → simp_lemmas → option expr → expr → tactic (A × expr × option expr × bool))
(post : A → simp_lemmas → name → option expr → expr → tactic (A × expr × option expr × bool))
/- simplification relation -/
(r : name) :
expr → tactic (A × expr × expr)

View file

@ -39,22 +39,18 @@ by conversion $
constant h : nat → nat → nat
meta def conv.depth : conv unit → conv unit
| c r e :=
(subc (conv.depth c) >> repeat c) r e
lemma ex (a : nat) : (λ a, h (f a (sizeof a)) (g a)) = (λ a, h 0 a) :=
by conversion $
depth_first $
bottom_up $
(apply_simp_set `foo <|> apply_simp_set `bla <|> dsimp)
lemma ex2 {A : Type} [comm_group A] (a b : A) : b * 1 * a = a * b :=
by conversion $
depth_first (apply_simp_set `default)
bottom_up (apply_simp_set `default)
lemma ex3 (p q r : Prop) : (p ∧ true ∧ p) = p :=
by conversion $
depth_first (apply_propext_simp_set `default)
bottom_up (apply_propext_simp_set `default)
print "---------"
@ -62,11 +58,11 @@ lemma ex4 (a b c : nat) : g (g (g (f (f (g (g a)) (g (g a))) a))) = g (g (g (f (
by conversion $
findp `(λ x, f (g x) (g x)) $
trace "found pattern" >> trace_lhs >>
depth_first (apply_simp_set `bla)
bottom_up (apply_simp_set `bla)
lemma ex5 (a b c : nat) : g (g (g (f (f (g (g a)) (g (g a))) a))) = g (g (g (f (f a a) a))) :=
by conversion $
find $
match_expr `(λ x, f (g x) (g x)) >>
trace "found pattern" >> trace_lhs >>
depth_first (apply_simp_set `bla)
bottom_up (apply_simp_set `bla)