Built with Alectryon, running Coq+SerAPI v8.16.0+0.16.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.

Formalizing variadic syntax with Tealeaves

let with letrec semantics

From Tealeaves Require Export
  Examples.VariadicLet.Terms
  Functors.List_Telescoping
  Adapters.Compositions.DecoratedTraversableModule.

#[local] Generalizable Variables G A B C.
#[local] Set Implicit Arguments.
#[local] Open Scope nat_scope.

#[local] Notation "'P'" := pure.
#[local] Notation "'BD'" := binddt.

Fixpoint binddt_term
  (G : Type -> Type) `{Map G} `{Pure G} `{Mult G}
  {v1 v2 : Type}
  (f : nat * v1 -> G (term v2))
  (t : term v1) : G (term v2) :=
  match t with
  | tvar v => f (0, v)
  | abs body => pure (@abs v2) <⋆> binddt_term (f ⦿ 1) body
  | letin defs body =>
      pure (@letin v2) <⋆>
        ((fix F ls :=
            match ls with
            | nil => pure nil
            | cons d drest =>
                pure cons <⋆> binddt_term (f ⦿ length defs) d <⋆> F drest
            end) defs) <⋆> binddt_term (f ⦿ length defs) body
  | app t1 t2 =>
      pure (@app v2) <⋆> binddt_term f t1 <⋆> binddt_term f t2
  end.

#[export] Instance Binddt_term: Binddt nat term term := @binddt_term.

#[export] Instance Map_term: Map term
  := DerivedOperations.Map_Binddt nat term term.
#[export] Instance Mapd_term: Mapd nat term
  := DerivedOperations.Mapd_Binddt nat term term.
#[export] Instance Traverse_term: Traverse term
  := DerivedOperations.Traverse_Binddt nat term term.
#[export] Instance Mapdt_term: Mapdt nat term
  := DerivedOperations.Mapdt_Binddt nat term term.
#[export] Instance Bind_term: Bind term term
  := DerivedOperations.Bind_Binddt nat term term.
#[export] Instance Bindd_term: Bindd nat term term
  := DerivedOperations.Bindd_Binddt nat term term.
#[export] Instance Bindt_term: Bindt term term
  := DerivedOperations.Bindt_Binddt nat term term.
#[export] Instance ToSubset_term: ToSubset term
  := ToSubset_Traverse.
#[export] Instance ToBatch_term: ToBatch term
  := DerivedOperations.ToBatch_Traverse.

Definition subst_in_defs
  `{Applicative G} {v1 v2 : Type}
  (f : nat * v1 -> G (term v2)):
  list (term v1) -> G (list (term v2)) :=
  binddt (Binddt := Mapdt_Binddt_compose (Mapdt_F := Mapdt_List_Full))
    (U := list ∘ term) f.

Section rewriting.

  Section pointful.

    Context
      `{Applicative G} (v1 v2 : Type)
        (f : nat * v1 -> G (term v2)).

    
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)

forall v : v1, BD f (tvar v) = f (Ƶ, v)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)

forall v : v1, BD f (tvar v) = f (Ƶ, v)
reflexivity. Qed.
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)

forall t : term v1, BD f (abs t) = P (abs (v:=v2)) <⋆> BD (f ⦿ 1) t
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)

forall t : term v1, BD f (abs t) = P (abs (v:=v2)) <⋆> BD (f ⦿ 1) t
reflexivity. Qed.
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)

forall (l : list (term v1)) (body : term v1), BD f (letin l body) = P (letin (v:=v2)) <⋆> subst_in_defs f l <⋆> BD (f ⦿ length l) body
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)

forall (l : list (term v1)) (body : term v1), BD f (letin l body) = P (letin (v:=v2)) <⋆> subst_in_defs f l <⋆> BD (f ⦿ length l) body
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

BD f (letin l body) = P (letin (v:=v2)) <⋆> subst_in_defs f l <⋆> BD (f ⦿ length l) body
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

P (letin (v:=v2)) <⋆> (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ length l) d <⋆> F drest end) l <⋆> BD (f ⦿ length l) body = P (letin (v:=v2)) <⋆> subst_in_defs f l <⋆> BD (f ⦿ length l) body
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ length l) d <⋆> F drest end) l = subst_in_defs f l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ length l) d <⋆> F drest end) l = BD f l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ length l) d <⋆> F drest end) l = mapdt (fun '(w1, t) => BD (f ⦿ w1) t) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ length l) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ∘ pair (length l)) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ length l) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ 0 ∘ pair (length l)) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + 0)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ 0 ∘ pair (length l)) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1
BD (f ⦿ (length l + 0)) = BD (f ⦿ length l)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

BD (f ⦿ (length l + 0)) = BD (f ⦿ length l)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

f ⦿ (length l + 0) = f ⦿ length l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

length l + 0 = length l
lia.
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)
l: list (term v1)
body: term v1

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + 0)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ 0 ∘ pair (length l)) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
l: list (term v1)
body: term v1

forall f : nat * v1 -> G (term v2), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + 0)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ 0 ∘ pair (length l)) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
l: list (term v1)
body: term v1

forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
body: term v1
n: nat
f: nat * v1 -> G (term v2)

P [] = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length [])) []
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
IHl: forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
n: nat
f: nat * v1 -> G (term v2)
P cons <⋆> BD (f ⦿ (length (a :: l) + n)) a <⋆> (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length (a :: l) + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length (a :: l))) (a :: l)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
body: term v1
n: nat
f: nat * v1 -> G (term v2)

P [] = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length [])) []
reflexivity.
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
IHl: forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
n: nat
f: nat * v1 -> G (term v2)

P cons <⋆> BD (f ⦿ (length (a :: l) + n)) a <⋆> (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length (a :: l) + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length (a :: l))) (a :: l)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
IHl: forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
n: nat
f: nat * v1 -> G (term v2)

P cons <⋆> BD (f ⦿ S (length l + n)) a <⋆> (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = P cons <⋆> BD (f ⦿ (n ● S (length l))) a <⋆> traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (S (length l))) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
IHl: forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
n: nat
f: nat * v1 -> G (term v2)

P cons <⋆> BD (f ⦿ S (length l + n)) a = P cons <⋆> BD (f ⦿ (n ● S (length l))) a
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
IHl: forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
n: nat
f: nat * v1 -> G (term v2)
(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (S (length l))) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
IHl: forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
n: nat
f: nat * v1 -> G (term v2)

P cons <⋆> BD (f ⦿ S (length l + n)) a = P cons <⋆> BD (f ⦿ (n ● S (length l))) a
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
IHl: forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
n: nat
f: nat * v1 -> G (term v2)

S (length l + n) = n ● S (length l)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
IHl: forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
n: nat
f: nat * v1 -> G (term v2)

S (length l + n) = n + S (length l)
lia.
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
IHl: forall (n : nat) (f : nat * v1 -> G (term v2)), (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (length l)) l
n: nat
f: nat * v1 -> G (term v2)

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (S (length l))) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
n: nat
f: nat * v1 -> G (term v2)
IHl: (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ (length l + S n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (S (length l))) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
n: nat
f: nat * v1 -> G (term v2)
IHl: (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l

(fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (S (length l))) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
n: nat
f: nat * v1 -> G (term v2)
IHl: (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l

traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (S (length l))) l
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
n: nat
f: nat * v1 -> G (term v2)
IHl: (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l

(fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l) = (fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (S (length l))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
n: nat
f: nat * v1 -> G (term v2)
IHl: (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l
t: term v1

((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) t = ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ n ∘ pair (S (length l))) t
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
n: nat
f: nat * v1 -> G (term v2)
IHl: (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l
t: term v1

BD (f ⦿ S (n ● length l)) t = BD (f ⦿ (n ● S (length l))) t
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
n: nat
f: nat * v1 -> G (term v2)
IHl: (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l
t: term v1

f ⦿ S (n ● length l) = f ⦿ (n ● S (length l))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
n: nat
f: nat * v1 -> G (term v2)
IHl: (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l
t: term v1

S (n ● length l) = n ● S (length l)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
a: term v1
l: list (term v1)
body: term v1
n: nat
f: nat * v1 -> G (term v2)
IHl: (fix F (ls : list (term v1)) : G (list (term v2)) := match ls with | [] => P [] | d :: drest => P cons <⋆> BD (f ⦿ S (length l + n)) d <⋆> F drest end) l = traverse ((fun '(w1, t) => BD (f ⦿ w1) t) ⦿ S n ∘ pair (length l)) l
t: term v1

S (n + length l) = n + S (length l)
lia. Qed.
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)

forall t1 t2 : term v1, BD f (app t1 t2) = P (app (v:=v2)) <⋆> BD f t1 <⋆> BD f t2
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
v1, v2: Type
f: nat * v1 -> G (term v2)

forall t1 t2 : term v1, BD f (app t1 t2) = P (app (v:=v2)) <⋆> BD f t1 <⋆> BD f t2
reflexivity. Qed. End pointful. Section pointfree. Context `{Applicative G2} {B C: Type} (g : nat * B -> G2 (term C)).
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)

forall l : list (term B), BD g ∘ letin l = (precompose (BD (g ⦿ length l)) ∘ ap G2) (P (letin (v:=C)) <⋆> subst_in_defs g l)
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)

forall l : list (term B), BD g ∘ letin l = (precompose (BD (g ⦿ length l)) ∘ ap G2) (P (letin (v:=C)) <⋆> subst_in_defs g l)
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
l: list (term B)

BD g ∘ letin l = (precompose (BD (g ⦿ length l)) ∘ ap G2) (P (letin (v:=C)) <⋆> subst_in_defs g l)
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
l: list (term B)
body: term B

(BD g ∘ letin l) body = (precompose (BD (g ⦿ length l)) ∘ ap G2) (P (letin (v:=C)) <⋆> subst_in_defs g l) body
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
l: list (term B)
body: term B

BD g (letin l body) = P (letin (v:=C)) <⋆> subst_in_defs g l <⋆> BD (g ⦿ length l) body
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
l: list (term B)
body: term B

P (letin (v:=C)) <⋆> subst_in_defs g l <⋆> BD (g ⦿ length l) body = P (letin (v:=C)) <⋆> subst_in_defs g l <⋆> BD (g ⦿ length l) body
reflexivity. Qed.
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)

forall (A : Type) (l : list A), compose (BD g) ∘ letin (v:=B) ∘ mapdt_make l = (compose (precompose (BD (g ⦿ length l)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C)) ∘ mapdt_make l
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)

forall (A : Type) (l : list A), compose (BD g) ∘ letin (v:=B) ∘ mapdt_make l = (compose (precompose (BD (g ⦿ length l)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C)) ∘ mapdt_make l
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
A: Type
l: list A

compose (BD g) ∘ letin (v:=B) ∘ mapdt_make l = (compose (precompose (BD (g ⦿ length l)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C)) ∘ mapdt_make l
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
A: Type
l: list A
l': Vector (plength l) (term B)
body: term B

(compose (BD g) ∘ letin (v:=B) ∘ mapdt_make l) l' body = ((compose (precompose (BD (g ⦿ length l)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C)) ∘ mapdt_make l) l' body
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
A: Type
l: list A
l': Vector (plength l) (term B)
body: term B

BD g (letin (mapdt_make l l') body) = P (letin (v:=C)) <⋆> subst_in_defs g (mapdt_make l l') <⋆> BD (g ⦿ length l) body
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
A: Type
l: list A
l': Vector (plength l) (term B)
body: term B

P (letin (v:=C)) <⋆> subst_in_defs g (mapdt_make l l') <⋆> BD (g ⦿ length (mapdt_make l l')) body = P (letin (v:=C)) <⋆> subst_in_defs g (mapdt_make l l') <⋆> BD (g ⦿ length l) body
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
A: Type
l: list A
l': Vector (plength l) (term B)
body: term B

P (letin (v:=C)) <⋆> subst_in_defs g (mapdt_make l l') <⋆> BD (g ⦿ plength (mapdt_make l l')) body = P (letin (v:=C)) <⋆> subst_in_defs g (mapdt_make l l') <⋆> BD (g ⦿ plength l) body
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
A: Type
l: list A
l': Vector (plength l) (term B)
body: term B

P (letin (v:=C)) <⋆> subst_in_defs g (trav_make l l') <⋆> BD (g ⦿ plength (trav_make l l')) body = P (letin (v:=C)) <⋆> subst_in_defs g (trav_make l l') <⋆> BD (g ⦿ plength l) body
G2: Type -> Type
Map_G: Map G2
Pure_G: Pure G2
Mult_G: Mult G2
H: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
A: Type
l: list A
l': Vector (plength l) (term B)
body: term B

P (letin (v:=C)) <⋆> subst_in_defs g (trav_make l l') <⋆> BD (g ⦿ plength l) body = P (letin (v:=C)) <⋆> subst_in_defs g (trav_make l l') <⋆> BD (g ⦿ plength l) body
reflexivity. Qed. End pointfree. End rewriting. Ltac simplify_binddt_term := match goal with | |- context[BD ?f (tvar ?y)] => ltac_trace "step_BD_tvar"; rewrite binddt_term_rw1 | |- context[((binddt ?f) (abs ?body))] => rewrite binddt_term_rw2 | |- context[((BD ?f) (letin ?l ?body))] => ltac_trace "step_BD_letin"; rewrite binddt_term_rw3 | |- context[((BD ?f) (app ?t1 ?t2))] => ltac_trace "step_BD_app"; rewrite binddt_term_rw4 end. Ltac cbn_binddt ::= simplify_binddt_term.

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> forall (A B : Type) (f : nat * A -> G (term B)), BD f ∘ ret = f ∘ ret

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> forall (A B : Type) (f : nat * A -> G (term B)), BD f ∘ ret = f ∘ ret
derive_dtm1. Qed.

forall A : Type, BD (ret ∘ extract) = id

forall A : Type, BD (ret ∘ extract) = id
A: Type

BD (ret ∘ extract) = id
A: Type
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> BD (ret ∘ extract) t = t
IHt: BD (ret ∘ extract) t = t

subst_in_defs (ret ∘ extract) defs = defs
A: Type
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> BD (ret ∘ extract) t = t
IHt: BD (ret ∘ extract) t = t

BD (ret ∘ extract) defs = defs
A: Type
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> BD (ret ∘ extract) t = t
IHt: BD (ret ∘ extract) t = t

mapdt (fun '(w1, t) => BD ((ret ∘ extract) ⦿ w1) t) defs = defs
A: Type
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> BD (ret ∘ extract) t = t
IHt: BD (ret ∘ extract) t = t
e: nat
a: term A
H: (e, a) ∈d defs

BD ((ret ∘ extract) ⦿ e) a = a
A: Type
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> BD (ret ∘ extract) t = t
IHt: BD (ret ∘ extract) t = t
e: nat
a: term A
H: (e, a) ∈d defs

BD (ret ∘ extract) a = a
A: Type
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> BD (ret ∘ extract) t = t
IHt: BD (ret ∘ extract) t = t
e: nat
a: term A
H: a ∈ defs

BD (ret ∘ extract) a = a
auto. Qed. Set Keyed Unification.

forall (G1 : Type -> Type) (Map_G : Map G1) (Pure_G : Pure G1) (Mult_G : Mult G1), Applicative G1 -> forall (G2 : Type -> Type) (Map_G0 : Map G2) (Pure_G0 : Pure G2) (Mult_G0 : Mult G2), Applicative G2 -> forall (B C : Type) (g : nat * B -> G2 (term C)) (A : Type) (f : nat * A -> G1 (term B)), map (BD g) ∘ BD f = BD (g ⋆7 f)

forall (G1 : Type -> Type) (Map_G : Map G1) (Pure_G : Pure G1) (Mult_G : Mult G1), Applicative G1 -> forall (G2 : Type -> Type) (Map_G0 : Map G2) (Pure_G0 : Pure G2) (Mult_G0 : Mult G2), Applicative G2 -> forall (B C : Type) (g : nat * B -> G2 (term C)) (A : Type) (f : nat * A -> G1 (term B)), map (BD g) ∘ BD f = BD (g ⋆7 f)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
A: Type
f: nat * A -> G1 (term B)

map (BD g) ∘ BD f = BD (g ⋆7 f)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)

P (compose (BD g) ∘ letin (v:=B)) <⋆> subst_in_defs f defs <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)

map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs
P (compose (BD g) ∘ letin (v:=B)) <⋆> subst_in_defs f defs <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)

map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)

map (BD g) (BD f defs) = BD (g ⋆7 f) defs
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)

map (mapdt (fun '(w1, t) => BD (g ⦿ w1) t)) (mapdt (fun '(w1, t) => BD (f ⦿ w1) t) defs) = mapdt (fun '(w1, t) => BD ((g ⋆7 f) ⦿ w1) t) defs
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)

(map (mapdt (fun '(w1, t) => BD (g ⦿ w1) t)) ∘ mapdt (fun '(w1, t) => BD (f ⦿ w1) t)) defs = mapdt (fun '(w1, t) => BD ((g ⋆7 f) ⦿ w1) t) defs
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)

mapdt ((fun '(w1, t) => BD (g ⦿ w1) t) ⋆3 (fun '(w1, t) => BD (f ⦿ w1) t)) defs = mapdt (fun '(w1, t) => BD ((g ⋆7 f) ⦿ w1) t) defs
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)

forall (e : nat) (a : term A), (e, a) ∈d defs -> ((fun '(w1, t) => BD (g ⦿ w1) t) ⋆3 (fun '(w1, t) => BD (f ⦿ w1) t)) ( e, a) = BD ((g ⋆7 f) ⦿ e) a
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
e: nat
t': term A
Hin: (e, t') ∈d defs

((fun '(w1, t) => BD (g ⦿ w1) t) ⋆3 (fun '(w1, t) => BD (f ⦿ w1) t)) ( e, t') = BD ((g ⋆7 f) ⦿ e) t'
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
e: nat
t': term A
Hin: (e, t') ∈d defs

map ((fun '(w1, t) => BD (g ⦿ w1) t) ∘ pair e) (BD (f ⦿ e) t') = BD ((g ⋆7 f) ⦿ e) t'
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
e: nat
t': term A
Hin: (e, t') ∈d defs

map ((fun '(w1, t) => BD (g ⦿ w1) t) ∘ pair e) (BD (f ⦿ e) t') = BD (g ⦿ e ⋆7 f ⦿ e) t'
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
e: nat
t': term A
Hin: t' ∈ defs

map ((fun '(w1, t) => BD (g ⦿ w1) t) ∘ pair e) (BD (f ⦿ e) t') = BD (g ⦿ e ⋆7 f ⦿ e) t'
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
e: nat
t': term A
Hin: t' ∈ defs

map ((fun '(w1, t) => BD (g ⦿ w1) t) ∘ pair e) (BD (f ⦿ e) t') = map (BD (g ⦿ e)) (BD (f ⦿ e) t')
reflexivity.
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P (compose (BD g) ∘ letin (v:=B)) <⋆> subst_in_defs f defs <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P (compose (BD g) ∘ letin (v:=B)) <⋆> BD f defs <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P (compose (BD g) ∘ letin (v:=B)) <⋆> mapdt (fun '(w1, t) => BD (f ⦿ w1) t) defs <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P (compose (BD g) ∘ letin (v:=B)) <⋆> map (mapdt_make defs) (forwards (traverse (mkBackwards ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) (mapdt_contents defs))) <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P (precompose (mapdt_make defs) (compose (BD g) ∘ letin (v:=B))) <⋆> forwards (traverse (mkBackwards ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) (mapdt_contents defs)) <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P (compose (BD g) ∘ letin (v:=B) ∘ mapdt_make defs) <⋆> forwards (traverse (mkBackwards ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) (mapdt_contents defs)) <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P ((compose (precompose (BD (g ⦿ length defs)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C)) ∘ mapdt_make defs) <⋆> forwards (traverse (mkBackwards ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) (mapdt_contents defs)) <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P (precompose (mapdt_make defs) ((compose (precompose (BD (g ⦿ length defs)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C)))) <⋆> forwards (traverse (mkBackwards ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) (mapdt_contents defs)) <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

map (precompose (mapdt_make defs)) (P ((compose (precompose (BD (g ⦿ length defs)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C)))) <⋆> forwards (traverse (mkBackwards ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) (mapdt_contents defs)) <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P ((compose (precompose (BD (g ⦿ length defs)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C))) <⋆> map (mapdt_make defs) (forwards (traverse (mkBackwards ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) (mapdt_contents defs))) <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P ((compose (precompose (BD (g ⦿ length defs)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C))) <⋆> mapdt (fun '(w1, t) => BD (f ⦿ w1) t) defs <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P ((compose (precompose (BD (g ⦿ length defs)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C))) <⋆> subst_in_defs f defs <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> subst_in_defs (g ⋆7 f) defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P ((compose (precompose (BD (g ⦿ length defs)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C))) <⋆> subst_in_defs f defs <⋆> BD (f ⦿ length defs) t = P (P (letin (v:=C))) <⋆> map (subst_in_defs g) (subst_in_defs f defs) <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P ((compose (precompose (BD (g ⦿ length defs)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C))) <⋆> subst_in_defs f defs <⋆> BD (f ⦿ length defs) t = P (precompose (subst_in_defs g) (ap G2 (P (letin (v:=C))))) <⋆> subst_in_defs f defs <⋆> map (BD (g ⦿ length defs)) (BD (f ⦿ length defs) t)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C, A: Type
H1: Functor G2
H2: Functor G1
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
IHt: forall (g : nat * B -> G2 (term C)) (f : nat * A -> G1 (term B)), map (BD g) (BD f t) = BD (g ⋆7 f) t
g: nat * B -> G2 (term C)
f: nat * A -> G1 (term B)
IHdefs': map (subst_in_defs g) (subst_in_defs f defs) = subst_in_defs (g ⋆7 f) defs

P ((compose (precompose (BD (g ⦿ length defs)) ∘ ap G2) ∘ precompose (subst_in_defs g) ∘ ap G2 ∘ P) (letin (v:=C))) <⋆> subst_in_defs f defs <⋆> BD (f ⦿ length defs) t = P (precompose (BD (g ⦿ length defs)) ∘ (ap G2 ∘ precompose (subst_in_defs g) (ap G2 (P (letin (v:=C)))))) <⋆> subst_in_defs f defs <⋆> BD (f ⦿ length defs) t
reflexivity. Qed.

forall (G1 G2 : Type -> Type) (H1 : Map G1) (H2 : Mult G1) (H3 : Pure G1) (H4 : Map G2) (H5 : Mult G2) (H6 : Pure G2) (ϕ : forall A : Type, G1 A -> G2 A), ApplicativeMorphism G1 G2 ϕ -> forall (A B : Type) (f : nat * A -> G1 (term B)), ϕ (term B) ∘ BD f = BD (ϕ (term B) ∘ f)

forall (G1 G2 : Type -> Type) (H1 : Map G1) (H2 : Mult G1) (H3 : Pure G1) (H4 : Map G2) (H5 : Mult G2) (H6 : Pure G2) (ϕ : forall A : Type, G1 A -> G2 A), ApplicativeMorphism G1 G2 ϕ -> forall (A B : Type) (f : nat * A -> G1 (term B)), ϕ (term B) ∘ BD f = BD (ϕ (term B) ∘ f)
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)

ϕ (list (term B)) (subst_in_defs f defs) = subst_in_defs (ϕ (term B) ∘ f) defs
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)

(ϕ (list (term B)) ∘ subst_in_defs f) defs = subst_in_defs (ϕ (term B) ∘ f) defs
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)

(ϕ (list (term B)) ∘ BD f) defs = BD (ϕ (term B) ∘ f) defs
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)

(ϕ (list (term B)) ∘ mapdt (fun '(w1, t) => BD (f ⦿ w1) t)) defs = mapdt (fun '(w1, t) => BD ((ϕ (term B) ∘ f) ⦿ w1) t) defs
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)

(ϕ (list (term B)) ∘ mapdt (fun '(w1, t) => BD (f ⦿ w1) t)) defs = mapdt (fun '(w1, t) => BD (ϕ (term B) ∘ f ⦿ w1) t) defs
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)

mapdt (ϕ (term B) ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) defs = mapdt (fun '(w1, t) => BD (ϕ (term B) ∘ f ⦿ w1) t) defs
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)

forall (e : nat) (a : term A), (e, a) ∈d defs -> (ϕ (term B) ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) (e, a) = BD (ϕ (term B) ∘ f ⦿ e) a
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)
e: nat
a: term A
Hin: (e, a) ∈d defs

(ϕ (term B) ∘ (fun '(w1, t) => BD (f ⦿ w1) t)) (e, a) = BD (ϕ (term B) ∘ f ⦿ e) a
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)
e: nat
a: term A
Hin: (e, a) ∈d defs

ϕ (term B) (BD (f ⦿ e) a) = BD (ϕ (term B) ○ f ⦿ e) a
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)
e: nat
a: term A
Hin: a ∈ defs

ϕ (term B) (BD (f ⦿ e) a) = BD (ϕ (term B) ○ f ⦿ e) a
G1, G2: Type -> Type
H1: Map G1
H2: Mult G1
H3: Pure G1
H4: Map G2
H5: Mult G2
H6: Pure G2
ϕ: forall A : Type, G1 A -> G2 A
H: ApplicativeMorphism G1 G2 ϕ
A, B: Type
H0: Applicative G1
H7: Functor G1
H8: Applicative G2
H9: Functor G2
defs: list (term A)
t: term A
IHdefs: forall t : term A, t ∈ defs -> forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
IHt: forall f : nat * A -> G1 (term B), ϕ (term B) (BD f t) = BD (ϕ (term B) ∘ f) t
f: nat * A -> G1 (term B)
e: nat
a: term A
Hin: a ∈ defs

a ∈ defs
assumption. Qed.

DecoratedTraversableMonad nat term

DecoratedTraversableMonad nat term

Monoid nat

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> forall (A B : Type) (f : nat * A -> G (term B)), BD f ∘ ret = f ∘ ret

DecoratedTraversableRightPreModule nat term term

Monoid nat
typeclasses eauto.

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> forall (A B : Type) (f : nat * A -> G (term B)), BD f ∘ ret = f ∘ ret
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B: Type
f: nat * A -> G (term B)

BD f ∘ ret = f ∘ ret
apply dtm1_term.

DecoratedTraversableRightPreModule nat term term

forall A : Type, BD (ret ∘ extract) = id

forall (G1 : Type -> Type) (Map_G : Map G1) (Pure_G : Pure G1) (Mult_G : Mult G1), Applicative G1 -> forall (G2 : Type -> Type) (Map_G0 : Map G2) (Pure_G0 : Pure G2) (Mult_G0 : Mult G2), Applicative G2 -> forall (B C : Type) (g : nat * B -> G2 (term C)) (A : Type) (f : nat * A -> G1 (term B)), map (BD g) ∘ BD f = BD (g ⋆7 f)

forall (G1 G2 : Type -> Type) (H : Map G1) (H0 : Mult G1) (H1 : Pure G1) (H2 : Map G2) (H3 : Mult G2) (H4 : Pure G2) (ϕ : forall A : Type, G1 A -> G2 A), ApplicativeMorphism G1 G2 ϕ -> forall (A B : Type) (f : nat * A -> G1 (term B)), ϕ (term B) ∘ BD f = BD (ϕ (term B) ∘ f)

forall A : Type, BD (ret ∘ extract) = id
apply dtm2_term.

forall (G1 : Type -> Type) (Map_G : Map G1) (Pure_G : Pure G1) (Mult_G : Mult G1), Applicative G1 -> forall (G2 : Type -> Type) (Map_G0 : Map G2) (Pure_G0 : Pure G2) (Mult_G0 : Mult G2), Applicative G2 -> forall (B C : Type) (g : nat * B -> G2 (term C)) (A : Type) (f : nat * A -> G1 (term B)), map (BD g) ∘ BD f = BD (g ⋆7 f)
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
B, C: Type
g: nat * B -> G2 (term C)
A: Type
f: nat * A -> G1 (term B)

map (BD g) ∘ BD f = BD (g ⋆7 f)
apply dtm3_term.

forall (G1 G2 : Type -> Type) (H : Map G1) (H0 : Mult G1) (H1 : Pure G1) (H2 : Map G2) (H3 : Mult G2) (H4 : Pure G2) (ϕ : forall A : Type, G1 A -> G2 A), ApplicativeMorphism G1 G2 ϕ -> forall (A B : Type) (f : nat * A -> G1 (term B)), ϕ (term B) ∘ BD f = BD (ϕ (term B) ∘ f)
apply dtm4_term. Qed.