l3lab/ntp-mathlib huggingface dataset:
/-- Composition of first-order embeddings. -/
@[trans]
def comp (hnp : N ↪[L] P) (hmn : M ↪[L] N) : M ↪[L] P where
  toFun := hnp ∘ hmn
  inj' := hnp.injective.comp hmn.injective
  -- Porting note: should be done by autoparam?
  map_fun' := by intros; simp only [Function.comp_apply, map_fun]; 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ↪[L] P
hmn : M ↪[L] N
n✝ : ℕ
f✝ : Functions L n✝
x✝ : Fin n✝ → M
⊢ funMap f✝ (⇑hnp ∘ ⇑hmn ∘ x✝) = funMap f✝ ((⇑hnp ∘ ⇑hmn) ∘ x✝)

Next tactic:
trivial
/-- Composition of first-order embeddings. -/
@[trans]
def comp (hnp : N ↪[L] P) (hmn : M ↪[L] N) : M ↪[L] P where
  toFun := hnp ∘ hmn
  inj' := hnp.injective.comp hmn.injective
  -- Porting note: should be done by autoparam?
  map_fun' := by intros; simp only [Function.comp_apply, map_fun]; trivial
  -- Porting note: should be done by autoparam?
  map_rel' := by 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ↪[L] P
hmn : M ↪[L] N
⊢ ∀ {n : ℕ} (r : Relations L n) (x : Fin n → M),
    RelMap r ({ toFun := ⇑hnp ∘ ⇑hmn, inj' := (_ : Function.Injective (⇑hnp ∘ ⇑hmn)) }.toFun ∘ x) ↔ RelMap r x

Next tactic:
intros
/-- Composition of first-order embeddings. -/
@[trans]
def comp (hnp : N ↪[L] P) (hmn : M ↪[L] N) : M ↪[L] P where
  toFun := hnp ∘ hmn
  inj' := hnp.injective.comp hmn.injective
  -- Porting note: should be done by autoparam?
  map_fun' := by intros; simp only [Function.comp_apply, map_fun]; trivial
  -- Porting note: should be done by autoparam?
  map_rel' := by intros; 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ↪[L] P
hmn : M ↪[L] N
n✝ : ℕ
r✝ : Relations L n✝
x✝ : Fin n✝ → M
⊢ RelMap r✝ ({ toFun := ⇑hnp ∘ ⇑hmn, inj' := (_ : Function.Injective (⇑hnp ∘ ⇑hmn)) }.toFun ∘ x✝) ↔ RelMap r✝ x✝

Next tactic:
rw [Function.comp.assoc, map_rel, map_rel]
@[simp]
theorem comp_toHom (hnp : N ↪[L] P) (hmn : M ↪[L] N) :
    (hnp.comp hmn).toHom = hnp.toHom.comp hmn.toHom := by
  

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ↪[L] P
hmn : M ↪[L] N
⊢ toHom (comp hnp hmn) = Hom.comp (toHom hnp) (toHom hmn)

Next tactic:
ext
@[simp]
theorem comp_toHom (hnp : N ↪[L] P) (hmn : M ↪[L] N) :
    (hnp.comp hmn).toHom = hnp.toHom.comp hmn.toHom := by
  ext
  

Proof state:
case h
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ↪[L] P
hmn : M ↪[L] N
x✝ : M
⊢ (toHom (comp hnp hmn)) x✝ = (Hom.comp (toHom hnp) (toHom hmn)) x✝

Next tactic:
simp only [coe_toHom, comp_apply, Hom.comp_apply]
instance : EquivLike (M ≃[L] N) M N where
  coe f := f.toFun
  inv f := f.invFun
  left_inv f := f.left_inv
  right_inv f := f.right_inv
  coe_injective' f g h₁ h₂ := by
    

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
f g : M ≃[L] N
h₁ : (fun f => f.toFun) f = (fun f => f.toFun) g
h₂ : (fun f => f.invFun) f = (fun f => f.invFun) g
⊢ f = g

Next tactic:
cases f
instance : EquivLike (M ≃[L] N) M N where
  coe f := f.toFun
  inv f := f.invFun
  left_inv f := f.left_inv
  right_inv f := f.right_inv
  coe_injective' f g h₁ h₂ := by
    cases f
    

Proof state:
case mk
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
g : M ≃[L] N
toEquiv✝ : M ≃ N
map_fun'✝ :
  ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M), Equiv.toFun toEquiv✝ (funMap f x) = funMap f (toEquiv✝.toFun ∘ x)
map_rel'✝ : ∀ {n : ℕ} (r : Relations L n) (x : Fin n → M), RelMap r (toEquiv✝.toFun ∘ x) ↔ RelMap r x
h₁ : (fun f => f.toFun) (mk toEquiv✝) = (fun f => f.toFun) g
h₂ : (fun f => f.invFun) (mk toEquiv✝) = (fun f => f.invFun) g
⊢ mk toEquiv✝ = g

Next tactic:
cases g
instance : EquivLike (M ≃[L] N) M N where
  coe f := f.toFun
  inv f := f.invFun
  left_inv f := f.left_inv
  right_inv f := f.right_inv
  coe_injective' f g h₁ h₂ := by
    cases f
    cases g
    

Proof state:
case mk.mk
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
toEquiv✝¹ : M ≃ N
map_fun'✝¹ :
  ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M), Equiv.toFun toEquiv✝¹ (funMap f x) = funMap f (toEquiv✝¹.toFun ∘ x)
map_rel'✝¹ : ∀ {n : ℕ} (r : Relations L n) (x : Fin n → M), RelMap r (toEquiv✝¹.toFun ∘ x) ↔ RelMap r x
toEquiv✝ : M ≃ N
map_fun'✝ :
  ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M), Equiv.toFun toEquiv✝ (funMap f x) = funMap f (toEquiv✝.toFun ∘ x)
map_rel'✝ : ∀ {n : ℕ} (r : Relations L n) (x : Fin n → M), RelMap r (toEquiv✝.toFun ∘ x) ↔ RelMap r x
h₁ : (fun f => f.toFun) (mk toEquiv✝¹) = (fun f => f.toFun) (mk toEquiv✝)
h₂ : (fun f => f.invFun) (mk toEquiv✝¹) = (fun f => f.invFun) (mk toEquiv✝)
⊢ mk toEquiv✝¹ = mk toEquiv✝

Next tactic:
simp only [mk.injEq]
instance : EquivLike (M ≃[L] N) M N where
  coe f := f.toFun
  inv f := f.invFun
  left_inv f := f.left_inv
  right_inv f := f.right_inv
  coe_injective' f g h₁ h₂ := by
    cases f
    cases g
    simp only [mk.injEq]
    

Proof state:
case mk.mk
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
toEquiv✝¹ : M ≃ N
map_fun'✝¹ :
  ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M), Equiv.toFun toEquiv✝¹ (funMap f x) = funMap f (toEquiv✝¹.toFun ∘ x)
map_rel'✝¹ : ∀ {n : ℕ} (r : Relations L n) (x : Fin n → M), RelMap r (toEquiv✝¹.toFun ∘ x) ↔ RelMap r x
toEquiv✝ : M ≃ N
map_fun'✝ :
  ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M), Equiv.toFun toEquiv✝ (funMap f x) = funMap f (toEquiv✝.toFun ∘ x)
map_rel'✝ : ∀ {n : ℕ} (r : Relations L n) (x : Fin n → M), RelMap r (toEquiv✝.toFun ∘ x) ↔ RelMap r x
h₁ : (fun f => f.toFun) (mk toEquiv✝¹) = (fun f => f.toFun) (mk toEquiv✝)
h₂ : (fun f => f.invFun) (mk toEquiv✝¹) = (fun f => f.invFun) (mk toEquiv✝)
⊢ toEquiv✝¹ = toEquiv✝

Next tactic:
ext x
instance : EquivLike (M ≃[L] N) M N where
  coe f := f.toFun
  inv f := f.invFun
  left_inv f := f.left_inv
  right_inv f := f.right_inv
  coe_injective' f g h₁ h₂ := by
    cases f
    cases g
    simp only [mk.injEq]
    ext x
    

Proof state:
case mk.mk.H
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
toEquiv✝¹ : M ≃ N
map_fun'✝¹ :
  ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M), Equiv.toFun toEquiv✝¹ (funMap f x) = funMap f (toEquiv✝¹.toFun ∘ x)
map_rel'✝¹ : ∀ {n : ℕ} (r : Relations L n) (x : Fin n → M), RelMap r (toEquiv✝¹.toFun ∘ x) ↔ RelMap r x
toEquiv✝ : M ≃ N
map_fun'✝ :
  ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M), Equiv.toFun toEquiv✝ (funMap f x) = funMap f (toEquiv✝.toFun ∘ x)
map_rel'✝ : ∀ {n : ℕ} (r : Relations L n) (x : Fin n → M), RelMap r (toEquiv✝.toFun ∘ x) ↔ RelMap r x
h₁ : (fun f => f.toFun) (mk toEquiv✝¹) = (fun f => f.toFun) (mk toEquiv✝)
h₂ : (fun f => f.invFun) (mk toEquiv✝¹) = (fun f => f.invFun) (mk toEquiv✝)
x : M
⊢ toEquiv✝¹ x = toEquiv✝ x

Next tactic:
exact Function.funext_iff.1 h₁ x
/-- The inverse of a first-order equivalence is a first-order equivalence. -/
@[symm]
def symm (f : M ≃[L] N) : N ≃[L] M :=
  { f.toEquiv.symm with
    map_fun' := fun n f' {x} => by
      

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
f : M ≃[L] N
src✝ : N ≃ M := f.symm
n : ℕ
f' : Functions L n
x : Fin n → N
⊢ Equiv.toFun
      { toFun := src✝.toFun, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
        right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
      (funMap f' x) =
    funMap f'
      ({ toFun := src✝.toFun, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
            right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }.toFun ∘
        x)

Next tactic:
simp only [Equiv.toFun_as_coe]
/-- The inverse of a first-order equivalence is a first-order equivalence. -/
@[symm]
def symm (f : M ≃[L] N) : N ≃[L] M :=
  { f.toEquiv.symm with
    map_fun' := fun n f' {x} => by
      simp only [Equiv.toFun_as_coe]
      

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
f : M ≃[L] N
src✝ : N ≃ M := f.symm
n : ℕ
f' : Functions L n
x : Fin n → N
⊢ f.symm (funMap f' x) = funMap f' (⇑f.symm ∘ x)

Next tactic:
rw [Equiv.symm_apply_eq]
/-- The inverse of a first-order equivalence is a first-order equivalence. -/
@[symm]
def symm (f : M ≃[L] N) : N ≃[L] M :=
  { f.toEquiv.symm with
    map_fun' := fun n f' {x} => by
      simp only [Equiv.toFun_as_coe]
      rw [Equiv.symm_apply_eq]
      

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
f : M ≃[L] N
src✝ : N ≃ M := f.symm
n : ℕ
f' : Functions L n
x : Fin n → N
⊢ funMap f' x = f.toEquiv (funMap f' (⇑f.symm ∘ x))

Next tactic:
refine' Eq.trans _ (f.map_fun' f' (f.toEquiv.symm ∘ x)).symm
/-- The inverse of a first-order equivalence is a first-order equivalence. -/
@[symm]
def symm (f : M ≃[L] N) : N ≃[L] M :=
  { f.toEquiv.symm with
    map_fun' := fun n f' {x} => by
      simp only [Equiv.toFun_as_coe]
      rw [Equiv.symm_apply_eq]
      refine' Eq.trans _ (f.map_fun' f' (f.toEquiv.symm ∘ x)).symm
      

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
f : M ≃[L] N
src✝ : N ≃ M := f.symm
n : ℕ
f' : Functions L n
x : Fin n → N
⊢ funMap f' x = funMap f' (f.toFun ∘ ⇑f.symm ∘ x)

Next tactic:
rw [← Function.comp.assoc, Equiv.toFun_as_coe, Equiv.self_comp_symm, Function.comp.left_id]
/-- The inverse of a first-order equivalence is a first-order equivalence. -/
@[symm]
def symm (f : M ≃[L] N) : N ≃[L] M :=
  { f.toEquiv.symm with
    map_fun' := fun n f' {x} => by
      simp only [Equiv.toFun_as_coe]
      rw [Equiv.symm_apply_eq]
      refine' Eq.trans _ (f.map_fun' f' (f.toEquiv.symm ∘ x)).symm
      rw [← Function.comp.assoc, Equiv.toFun_as_coe, Equiv.self_comp_symm, Function.comp.left_id]
    map_rel' := fun n r {x} => by
      

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
f : M ≃[L] N
src✝ : N ≃ M := f.symm
n : ℕ
r : Relations L n
x : Fin n → N
⊢ RelMap r
      ({ toFun := src✝.toFun, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
            right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }.toFun ∘
        x) ↔
    RelMap r x

Next tactic:
simp only [Equiv.toFun_as_coe]
/-- The inverse of a first-order equivalence is a first-order equivalence. -/
@[symm]
def symm (f : M ≃[L] N) : N ≃[L] M :=
  { f.toEquiv.symm with
    map_fun' := fun n f' {x} => by
      simp only [Equiv.toFun_as_coe]
      rw [Equiv.symm_apply_eq]
      refine' Eq.trans _ (f.map_fun' f' (f.toEquiv.symm ∘ x)).symm
      rw [← Function.comp.assoc, Equiv.toFun_as_coe, Equiv.self_comp_symm, Function.comp.left_id]
    map_rel' := fun n r {x} => by
      simp only [Equiv.toFun_as_coe]
      

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
f : M ≃[L] N
src✝ : N ≃ M := f.symm
n : ℕ
r : Relations L n
x : Fin n → N
⊢ RelMap r (⇑f.symm ∘ x) ↔ RelMap r x

Next tactic:
refine' (f.map_rel' r (f.toEquiv.symm ∘ x)).symm.trans _
/-- The inverse of a first-order equivalence is a first-order equivalence. -/
@[symm]
def symm (f : M ≃[L] N) : N ≃[L] M :=
  { f.toEquiv.symm with
    map_fun' := fun n f' {x} => by
      simp only [Equiv.toFun_as_coe]
      rw [Equiv.symm_apply_eq]
      refine' Eq.trans _ (f.map_fun' f' (f.toEquiv.symm ∘ x)).symm
      rw [← Function.comp.assoc, Equiv.toFun_as_coe, Equiv.self_comp_symm, Function.comp.left_id]
    map_rel' := fun n r {x} => by
      simp only [Equiv.toFun_as_coe]
      refine' (f.map_rel' r (f.toEquiv.symm ∘ x)).symm.trans _
      

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
f : M ≃[L] N
src✝ : N ≃ M := f.symm
n : ℕ
r : Relations L n
x : Fin n → N
⊢ RelMap r (f.toFun ∘ ⇑f.symm ∘ x) ↔ RelMap r x

Next tactic:
rw [← Function.comp.assoc, Equiv.toFun_as_coe, Equiv.self_comp_symm, Function.comp.left_id]
@[simp]
theorem refl_apply (x : M) : refl L M x = x := by 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
x : M
⊢ (refl L M) x = x

Next tactic:
simp [refl]
@[simp]
theorem refl_apply (x : M) : refl L M x = x := by simp [refl]; 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
x : M
⊢ (mk (_root_.Equiv.refl M)) x = x

Next tactic:
rfl
/-- Composition of first-order equivalences. -/
@[trans]
def comp (hnp : N ≃[L] P) (hmn : M ≃[L] N) : M ≃[L] P :=
  { hmn.toEquiv.trans hnp.toEquiv with
    toFun := hnp ∘ hmn
    -- Porting note: should be done by autoparam?
    map_fun' := by 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ≃[L] P
hmn : M ≃[L] N
src✝ : M ≃ P := hmn.trans hnp.toEquiv
⊢ ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M),
    Equiv.toFun
        { toFun := ⇑hnp ∘ ⇑hmn, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
          right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
        (funMap f x) =
      funMap f
        ({ toFun := ⇑hnp ∘ ⇑hmn, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
              right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }.toFun ∘
          x)

Next tactic:
intros
/-- Composition of first-order equivalences. -/
@[trans]
def comp (hnp : N ≃[L] P) (hmn : M ≃[L] N) : M ≃[L] P :=
  { hmn.toEquiv.trans hnp.toEquiv with
    toFun := hnp ∘ hmn
    -- Porting note: should be done by autoparam?
    map_fun' := by intros; 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ≃[L] P
hmn : M ≃[L] N
src✝ : M ≃ P := hmn.trans hnp.toEquiv
n✝ : ℕ
f✝ : Functions L n✝
x✝ : Fin n✝ → M
⊢ Equiv.toFun
      { toFun := ⇑hnp ∘ ⇑hmn, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
        right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
      (funMap f✝ x✝) =
    funMap f✝
      ({ toFun := ⇑hnp ∘ ⇑hmn, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
            right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }.toFun ∘
        x✝)

Next tactic:
simp only [Function.comp_apply, map_fun]
/-- Composition of first-order equivalences. -/
@[trans]
def comp (hnp : N ≃[L] P) (hmn : M ≃[L] N) : M ≃[L] P :=
  { hmn.toEquiv.trans hnp.toEquiv with
    toFun := hnp ∘ hmn
    -- Porting note: should be done by autoparam?
    map_fun' := by intros; simp only [Function.comp_apply, map_fun]; 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ≃[L] P
hmn : M ≃[L] N
src✝ : M ≃ P := hmn.trans hnp.toEquiv
n✝ : ℕ
f✝ : Functions L n✝
x✝ : Fin n✝ → M
⊢ funMap f✝ (⇑hnp ∘ ⇑hmn ∘ x✝) = funMap f✝ ((⇑hnp ∘ ⇑hmn) ∘ x✝)

Next tactic:
trivial
/-- Composition of first-order equivalences. -/
@[trans]
def comp (hnp : N ≃[L] P) (hmn : M ≃[L] N) : M ≃[L] P :=
  { hmn.toEquiv.trans hnp.toEquiv with
    toFun := hnp ∘ hmn
    -- Porting note: should be done by autoparam?
    map_fun' := by intros; simp only [Function.comp_apply, map_fun]; trivial
    -- Porting note: should be done by autoparam?
    map_rel' := by 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ≃[L] P
hmn : M ≃[L] N
src✝ : M ≃ P := hmn.trans hnp.toEquiv
⊢ ∀ {n : ℕ} (r : Relations L n) (x : Fin n → M),
    RelMap r
        ({ toFun := ⇑hnp ∘ ⇑hmn, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
              right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }.toFun ∘
          x) ↔
      RelMap r x

Next tactic:
intros
/-- Composition of first-order equivalences. -/
@[trans]
def comp (hnp : N ≃[L] P) (hmn : M ≃[L] N) : M ≃[L] P :=
  { hmn.toEquiv.trans hnp.toEquiv with
    toFun := hnp ∘ hmn
    -- Porting note: should be done by autoparam?
    map_fun' := by intros; simp only [Function.comp_apply, map_fun]; trivial
    -- Porting note: should be done by autoparam?
    map_rel' := by intros; 

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
hnp : N ≃[L] P
hmn : M ≃[L] N
src✝ : M ≃ P := hmn.trans hnp.toEquiv
n✝ : ℕ
r✝ : Relations L n✝
x✝ : Fin n✝ → M
⊢ RelMap r✝
      ({ toFun := ⇑hnp ∘ ⇑hmn, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
            right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }.toFun ∘
        x✝) ↔
    RelMap r✝ x✝

Next tactic:
rw [Function.comp.assoc, map_rel, map_rel]
instance : Unique (Language.empty.Structure M) :=
  ⟨⟨Language.emptyStructure⟩, fun a => by
    

Proof state:
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
a : Structure Language.empty M
⊢ a = default

Next tactic:
ext _ f
instance : Unique (Language.empty.Structure M) :=
  ⟨⟨Language.emptyStructure⟩, fun a => by
    ext _ f <;> 

Proof state:
case funMap.h.h.h
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
a : Structure Language.empty M
x✝¹ : ℕ
f : Functions Language.empty x✝¹
x✝ : Fin x✝¹ → M
⊢ funMap f x✝ = funMap f x✝

Next tactic:
exact Empty.elim f
instance : Unique (Language.empty.Structure M) :=
  ⟨⟨Language.emptyStructure⟩, fun a => by
    ext _ f <;> 

Proof state:
case RelMap.h.h.h.a
L : Language
L' : Language
M : Type w
N : Type w'
inst✝³ : Structure L M
inst✝² : Structure L N
P : Type u_1
inst✝¹ : Structure L P
Q : Type u_2
inst✝ : Structure L Q
a : Structure Language.empty M
x✝¹ : ℕ
f : Relations Language.empty x✝¹
x✝ : Fin x✝¹ → M
⊢ RelMap f x✝ ↔ RelMap f x✝

Next tactic:
exact Empty.elim f
/-- A bijection as a first-order isomorphism with the induced structure on the codomain. -/
--@[simps!] Porting note: commented out and lemmas added manually
def inducedStructureEquiv (e : M ≃ N) : @Language.Equiv L M N _ (inducedStructure e) := by
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
inst✝ : Structure L M
e : M ≃ N
⊢ M ≃[L] N

Next tactic:
letI : L.Structure N := inducedStructure e
/-- A bijection as a first-order isomorphism with the induced structure on the codomain. -/
--@[simps!] Porting note: commented out and lemmas added manually
def inducedStructureEquiv (e : M ≃ N) : @Language.Equiv L M N _ (inducedStructure e) := by
  letI : L.Structure N := inducedStructure e
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
inst✝ : Structure L M
e : M ≃ N
this : Structure L N := inducedStructure e
⊢ M ≃[L] N

Next tactic:
exact
  { e with
    map_fun' := @fun n f x => by simp [← Function.comp.assoc e.symm e x]
    map_rel' := @fun n r x => by simp [← Function.comp.assoc e.symm e x] }
/-- A bijection as a first-order isomorphism with the induced structure on the codomain. -/
--@[simps!] Porting note: commented out and lemmas added manually
def inducedStructureEquiv (e : M ≃ N) : @Language.Equiv L M N _ (inducedStructure e) := by
  letI : L.Structure N := inducedStructure e
  exact
  { e with
    map_fun' := @fun n f x => by 

Proof state:
L : Language
M : Type u_1
N : Type u_2
inst✝ : Structure L M
e : M ≃ N
this : Structure L N := inducedStructure e
n : ℕ
f : Functions L n
x : Fin n → M
⊢ Equiv.toFun
      { toFun := e.toFun, invFun := e.invFun, left_inv := (_ : Function.LeftInverse e.invFun e.toFun),
        right_inv := (_ : Function.RightInverse e.invFun e.toFun) }
      (funMap f x) =
    funMap f
      ({ toFun := e.toFun, invFun := e.invFun, left_inv := (_ : Function.LeftInverse e.invFun e.toFun),
            right_inv := (_ : Function.RightInverse e.invFun e.toFun) }.toFun ∘
        x)

Next tactic:
simp [← Function.comp.assoc e.symm e x]
/-- A bijection as a first-order isomorphism with the induced structure on the codomain. -/
--@[simps!] Porting note: commented out and lemmas added manually
def inducedStructureEquiv (e : M ≃ N) : @Language.Equiv L M N _ (inducedStructure e) := by
  letI : L.Structure N := inducedStructure e
  exact
  { e with
    map_fun' := @fun n f x => by simp [← Function.comp.assoc e.symm e x]
    map_rel' := @fun n r x => by 

Proof state:
L : Language
M : Type u_1
N : Type u_2
inst✝ : Structure L M
e : M ≃ N
this : Structure L N := inducedStructure e
n : ℕ
r : Relations L n
x : Fin n → M
⊢ RelMap r
      ({ toFun := e.toFun, invFun := e.invFun, left_inv := (_ : Function.LeftInverse e.invFun e.toFun),
            right_inv := (_ : Function.RightInverse e.invFun e.toFun) }.toFun ∘
        x) ↔
    RelMap r x

Next tactic:
simp [← Function.comp.assoc e.symm e x]
@[simp]
theorem toFun_inducedStructureEquiv_Symm (e : M ≃ N) :
    (by
    

Proof state:
L : Language
M : Type u_1
N : Type u_2
inst✝ : Structure L M
e : M ≃ N
⊢ N → M

Next tactic:
letI : L.Structure N := inducedStructure e
@[simp]
theorem toFun_inducedStructureEquiv_Symm (e : M ≃ N) :
    (by
    letI : L.Structure N := inducedStructure e
    

Proof state:
L : Language
M : Type u_1
N : Type u_2
inst✝ : Structure L M
e : M ≃ N
this : Structure L N := inducedStructure e
⊢ N → M

Next tactic:
exact FunLike.coe (@inducedStructureEquiv L M N _ e).symm
@[simp]
theorem preimage_Iic (e : α ≃o β) (b : β) : e ⁻¹' Iic b = Iic (e.symm b) := by
  

Proof state:
α : Type u_2
β : Type u_1
inst✝¹ : Preorder α
inst✝ : Preorder β
e : α ≃o β
b : β
⊢ ⇑e ⁻¹' Iic b = Iic ((symm e) b)

Next tactic:
ext x
@[simp]
theorem preimage_Iic (e : α ≃o β) (b : β) : e ⁻¹' Iic b = Iic (e.symm b) := by
  ext x
  

Proof state:
case h
α : Type u_2
β : Type u_1
inst✝¹ : Preorder α
inst✝ : Preorder β
e : α ≃o β
b : β
x : α
⊢ x ∈ ⇑e ⁻¹' Iic b ↔ x ∈ Iic ((symm e) b)

Next tactic:
simp [← e.le_iff_le]
@[simp]
theorem preimage_Ici (e : α ≃o β) (b : β) : e ⁻¹' Ici b = Ici (e.symm b) := by
  

Proof state:
α : Type u_2
β : Type u_1
inst✝¹ : Preorder α
inst✝ : Preorder β
e : α ≃o β
b : β
⊢ ⇑e ⁻¹' Ici b = Ici ((symm e) b)

Next tactic:
ext x