feat(library/data/dlist): setup transfer for dlist

This commit is contained in:
Johannes Hölzl 2017-03-07 20:02:53 -05:00 committed by Leonardo de Moura
parent 9d62638e9a
commit d6eae3265c
3 changed files with 61 additions and 6 deletions

View file

@ -85,4 +85,57 @@ by cases l; rsimp
lemma to_list_concat (x : α) (l : dlist α) : to_list (concat x l) = to_list l ++ [x] :=
by cases l; simp; rsimp
section transfer
protected def rel_dlist_list (d : dlist α) (l : list α) : Prop :=
to_list d = l
instance bi_total_rel_dlist_list : @relator.bi_total (dlist α) (list α) dlist.rel_dlist_list :=
⟨take d, ⟨to_list d, rfl⟩, take l, ⟨of_list l, to_list_of_list l⟩⟩
protected lemma rel_eq :
(dlist.rel_dlist_list ⇒ dlist.rel_dlist_list ⇒ iff) (@eq (dlist α)) eq
| l₁ ._ rfl l₂ ._ rfl := ⟨congr_arg to_list,
suppose to_list l₁ = to_list l₂,
have of_list (to_list l₁) = of_list (to_list l₂), from congr_arg of_list this,
by simp [of_list_to_list] at this; assumption⟩
protected lemma rel_empty : dlist.rel_dlist_list (@empty α) [] :=
to_list_empty
protected lemma rel_singleton : (@eq α ⇒ dlist.rel_dlist_list) (λx, singleton x) (λx, [x])
| ._ x rfl := to_list_singleton x
protected lemma rel_append :
(dlist.rel_dlist_list ⇒ dlist.rel_dlist_list ⇒ dlist.rel_dlist_list) (λ(x y : dlist α), x ++ y) (λx y, x ++ y)
| l₁ ._ rfl l₂ ._ rfl := to_list_append l₁ l₂
protected lemma rel_cons :
(@eq α ⇒ dlist.rel_dlist_list ⇒ dlist.rel_dlist_list) cons (λx y, x :: y)
| x ._ rfl l ._ rfl := to_list_cons x l
protected lemma rel_concat :
(@eq α ⇒ dlist.rel_dlist_list ⇒ dlist.rel_dlist_list) concat (λx y, y ++ [x])
| x ._ rfl l ._ rfl := to_list_concat x l
protected meta def transfer : tactic unit := do
transfer.transfer [`relator.rel_forall_of_total, `dlist.rel_eq, `dlist.rel_empty,
`dlist.rel_singleton, `dlist.rel_append, `dlist.rel_cons, `dlist.rel_concat]
example : ∀(a b c : dlist α), a ++ (b ++ c) = (a ++ b) ++ c :=
begin
dlist.transfer,
intros,
simp
end
example : ∀(a : α), singleton a ++ empty = singleton a :=
begin
dlist.transfer,
intros,
simp
end
end transfer
end dlist

View file

@ -83,7 +83,7 @@ private meta def mark_occurences (e : expr) : list expr → list (expr × bool)
| (h :: t) := let xs := mark_occurences t in
(h, occurs h e || any xs (λ⟨e, oc⟩, oc && occurs h e)) :: xs
private meta def analyse_rule (pr : expr) : tactic rule_data := do
private meta def analyse_rule (u' : list name) (pr : expr) : tactic rule_data := do
t ← infer_type pr,
(params, app (app r f) g) ← mk_local_pis t,
(arg_rels, R) ← get_lift_fun r,
@ -93,8 +93,7 @@ private meta def analyse_rule (pr : expr) : tactic rule_data := do
p ← head_beta (app_of_list f a_vars),
p_data ← return $ mark_occurences (app R p) params,
p_vars ← return $ list.map prod.fst (list.filter (λx, ↑x.2) p_data),
u' ← return $ collect_univ_params t,
u ← return $ collect_univ_params (app R p),
u ← return $ collect_univ_params (app R p) ∩ u',
pat ← mk_pattern (fmap level.param u) (p_vars ++ a_vars) (app R p) (fmap level.param u) (p_vars ++ a_vars),
return $ rule_data.mk pr (list.remove_all u' u) p_data u args pat g
@ -102,8 +101,8 @@ private meta def analyse_decls : list name → tactic (list rule_data) :=
monad.mapm (λn, do
d ← get_decl n,
c ← return d^.univ_params^.length,
l ← monad.for (range c) (λ_, level.param <$> mk_fresh_name),
analyse_rule (const n l))
ls ← monad.for (range c) (λ_, mk_fresh_name),
analyse_rule ls (const n (ls^.map level.param)))
private meta def split_params_args : list (expr × bool) → list expr → list (expr × option expr) × list expr
| ((lc, tt) :: ps) (e :: es) := let (ps', es') := split_params_args ps es in ((lc, some e) :: ps', es')
@ -154,7 +153,7 @@ meta def compute_transfer : list rule_data → list expr → expr → tactic (ex
b ← mk_local_def (("b" ++ to_string n) : string) arg^.out_type,
R ← mk_local_def (("R" ++ to_string n) : string) (arg^.relation a b),
return ((a, b), (R, [a, b, R]))) >>= (return ∘ prod.map unzip unzip ∘ unzip),
rds' ← monad.for R_vars analyse_rule,
rds' ← monad.for R_vars (analyse_rule []),
-- Transfer argument
a ← return $ i e,

View file

@ -67,4 +67,7 @@ take p q h r s l, imp_congr h l
lemma rel_not : (iff ⇒ iff) not not :=
take p q h, not_congr h
instance bi_total_eq {α : Type u₁} : relator.bi_total (@eq α) :=
⟨take a, ⟨a, rfl⟩, take a, ⟨a, rfl⟩⟩
end relator