275 lines
7.1 KiB
Text
275 lines
7.1 KiB
Text
open tactic
|
||
|
||
/-
|
||
Given a metavariable ?m with local context
|
||
|
||
(α : Type) (a : α)
|
||
|
||
then, the following unification problem should fail
|
||
|
||
?m α =?= ((λ (α : Type) (a : α), α) α a)
|
||
|
||
type_context will try the type incorrect assignment
|
||
|
||
?m := λ α', ((λ (α : Type) (a : α), α) α' a)
|
||
-/
|
||
def ex1 (α : Type) (a : α) : Type → Type :=
|
||
by do
|
||
fail_if_success
|
||
(do
|
||
mvar1 ← mk_meta_var `(Type → Type),
|
||
alpha ← to_expr ```(α),
|
||
t ← to_expr ```((λ (α : Type) (a : α), α) α a),
|
||
unify (mvar1 alpha) t semireducible tt, -- should fail
|
||
exact mvar1),
|
||
intros, assumption
|
||
|
||
/-
|
||
Given metavariable ?m_1 and ?m_2 with local context
|
||
|
||
(α : Type) (a : α)
|
||
|
||
then, the following unification constrains should be solved
|
||
|
||
?m_1 α =?= id ?m_2
|
||
?m_2 =?= α
|
||
|
||
The first constraint is solved using first-order unification
|
||
because we cannot guarantee that the solution will be type correct
|
||
for every term we may assign to `?m_2`
|
||
|
||
?m_1 := λ α', id ?m_2[α := α']
|
||
|
||
So, we get `?m_2 := α`.
|
||
|
||
Remark: see option c) at workaround A2 described at type_context::process_assignment
|
||
-/
|
||
def ex2 (α : Type) (a : α) : Type → Type :=
|
||
by do
|
||
mvar1 ← mk_meta_var `(Type → Type),
|
||
mvar2 ← mk_meta_var `(Type),
|
||
alpha ← to_expr ```(α),
|
||
t ← to_expr ```(id %%mvar2),
|
||
unify (mvar1 alpha) t semireducible tt, -- first-order unification is used here
|
||
unify mvar2 alpha,
|
||
exact mvar1
|
||
|
||
/-
|
||
Given metavariable ?m_1 and ?m_2 with local context
|
||
|
||
(α : Type) (a : α)
|
||
|
||
then, the following unification constrains should be solved
|
||
|
||
?m_1 α =?= id ?m_2
|
||
?m_2 =?= ((λ (α : Type) (a : α), α) α a)
|
||
|
||
Again, similarly to the previous example, we use
|
||
first-order unification to process the first constraint,
|
||
and we get `?m_2 := α`. The second constraint
|
||
is satisfied because `((λ (α : Type) (a : α), α) α a)`
|
||
is definitionally equal to `α`.
|
||
-/
|
||
def ex3 (α : Type) (a : α) : Type → Type :=
|
||
by do
|
||
mvar1 ← mk_meta_var `(Type → Type),
|
||
mvar2 ← mk_meta_var `(Type),
|
||
alpha ← to_expr ```(α),
|
||
t ← to_expr ```(id %%mvar2),
|
||
unify (mvar1 alpha) t semireducible tt, -- should create an auxiliary mvar and assign it to mvar2
|
||
t ← to_expr ```((λ (α : Type) (a : α), α) α a),
|
||
unify mvar2 t semireducible tt, -- should fail `a` is not in the scope
|
||
exact mvar1
|
||
|
||
def f (α : Type) (a : α) := α
|
||
|
||
constant f' (α : Type) (a : α) : Type
|
||
|
||
/-
|
||
Given a metavariable ?m with local context
|
||
|
||
(α : Type) (a : α)
|
||
|
||
then, the following unification problem should fail
|
||
|
||
?m α =?= f α a
|
||
|
||
type_context will try the type incorrect assignment
|
||
|
||
?m := λ α', f α' a
|
||
-/
|
||
def ex4 (α : Type) (a : α) : Type → Type :=
|
||
by do
|
||
fail_if_success
|
||
(do
|
||
mvar1 ← mk_meta_var `(Type → Type),
|
||
alpha ← to_expr ```(α),
|
||
t ← to_expr ```(f α a),
|
||
unify (mvar1 alpha) t semireducible tt, -- should fail
|
||
exact mvar1),
|
||
intros, assumption
|
||
|
||
/-
|
||
Given a metavariable ?m with local context
|
||
|
||
(α : Type) (a : α)
|
||
|
||
then, the following unification problem should work
|
||
|
||
?m α a =?= f α a
|
||
|
||
type_context assigns
|
||
|
||
?m := λ α' a', f α' a'
|
||
-/
|
||
def ex5 (α : Type) (a : α) : Π A : Type, A → Type :=
|
||
by do
|
||
mvar1 ← mk_meta_var `(Π A : Type, A → Type),
|
||
alpha ← to_expr ```(α),
|
||
a ← to_expr ```(a),
|
||
t ← to_expr ```(f α a),
|
||
unify (mvar1 alpha a) t semireducible tt, -- should work
|
||
exact mvar1
|
||
|
||
def ex5b (α : Type) (a : α) : Π A : Type, A → Type :=
|
||
by do
|
||
mvar1 ← mk_meta_var `(Π A : Type, A → Type),
|
||
alpha ← to_expr ```(α),
|
||
a ← to_expr ```(a),
|
||
t ← to_expr ```(f' α a),
|
||
unify (mvar1 alpha a) t semireducible tt, -- should work
|
||
exact mvar1
|
||
|
||
/-
|
||
Given metavariable ?m_1 and ?m_2 with local context
|
||
|
||
(α : Type) (a : α)
|
||
|
||
then, the following unification constrains should be solved
|
||
|
||
?m_1 α =?= id ?m_2
|
||
?m_2 =?= f α a
|
||
|
||
The first constraint is solved using first-order unification.
|
||
See option c) at workaround A2 described at type_context::process_assignment.
|
||
Then, we get `?m_2 := α`. The second constraint succeeds
|
||
because `f α a` is definitionally equal to `α`.
|
||
-/
|
||
def ex6 (α : Type) (a : α) : Type → Type :=
|
||
by do mvar1 ← mk_meta_var `(Type → Type),
|
||
mvar2 ← mk_meta_var `(Type),
|
||
alpha ← to_expr ```(α),
|
||
t ← to_expr ```(id %%mvar2),
|
||
unify (mvar1 alpha) t semireducible tt,
|
||
t ← to_expr ```(f α a),
|
||
unify mvar2 t semireducible tt,
|
||
exact mvar1
|
||
|
||
/-
|
||
Given metavariable ?m_1 and ?m_2 with local context
|
||
|
||
(α : Type) (a : α)
|
||
|
||
then, the following unification constrains should be solved
|
||
|
||
?m_1 α =?= id ?m_2
|
||
?m_2 =?= f' α a
|
||
|
||
Similar to previous example, but this one fails because
|
||
`f' α a` is not definitionally equal to `α`.
|
||
-/
|
||
def ex6b (α : Type) (a : α) : Type → Type :=
|
||
by do
|
||
fail_if_success
|
||
(do mvar1 ← mk_meta_var `(Type → Type),
|
||
mvar2 ← mk_meta_var `(Type),
|
||
alpha ← to_expr ```(α),
|
||
t ← to_expr ```(id %%mvar2),
|
||
unify (mvar1 alpha) t semireducible tt,
|
||
t ← to_expr ```(f' α a),
|
||
unify mvar2 t semireducible tt,
|
||
exact mvar1),
|
||
intros, assumption
|
||
|
||
def g (α : Type) (a b : α) := α
|
||
|
||
/-
|
||
Given a metavariable ?m with local context
|
||
|
||
(α : Type) (a : α)
|
||
|
||
then, the following unification problem should fail
|
||
|
||
?m α =?= g α a a
|
||
|
||
type_context will try the type incorrect assignment
|
||
|
||
?m := λ α', g α' a a
|
||
-/
|
||
def ex7 (α : Type) (a : α) : Type → Type :=
|
||
by do
|
||
fail_if_success
|
||
(do
|
||
mvar1 ← mk_meta_var `(Type → Type),
|
||
alpha ← to_expr ```(α),
|
||
t ← to_expr ```(g α a a),
|
||
unify (mvar1 alpha) t semireducible tt, -- should fail
|
||
exact mvar1),
|
||
intros, assumption
|
||
|
||
constant C (α : Type) (a : α) : Type
|
||
|
||
/-
|
||
Given a metavariable ?m with local context
|
||
|
||
(α : Type) (a : α) (x : C α a)
|
||
|
||
then, the following unification problem should fail
|
||
|
||
?m α x =?= α
|
||
|
||
type_context will try the type incorrect assignment
|
||
|
||
?m := λ (α' : Type) (x' : C α' a), α'
|
||
|
||
type_context detects the problem when it tries to unify the type of `?m`
|
||
with type of (λ (α' : Type) (x' : C α' a), α')
|
||
-/
|
||
def ex8 (α : Type) (a : α) (x : C α a) : Type :=
|
||
by do
|
||
fail_if_success
|
||
(do
|
||
mvar_type ← to_expr ```(C α a → Type),
|
||
mvar_type ← to_expr ```(Type → %%mvar_type),
|
||
mvar1 ← mk_meta_var mvar_type,
|
||
alpha ← to_expr ```(α),
|
||
x ← to_expr ```(x),
|
||
unify (mvar1 alpha x) alpha semireducible tt, -- should fail
|
||
exact (mvar1 alpha x)),
|
||
assumption
|
||
|
||
/-
|
||
Given a metavariable ?m with local context
|
||
|
||
(α : Type) (a : α)
|
||
|
||
then, the following unification problem should work
|
||
|
||
?m α =?= a
|
||
|
||
type_context assigns
|
||
|
||
?m := λ α', a
|
||
|
||
The point of this example is to make sure
|
||
future modifications to type_context do not
|
||
prevent us from solving valid problems like this one.
|
||
-/
|
||
def ex9 (α : Type) (a : α) : Type → α :=
|
||
by do
|
||
mvar_type ← to_expr ```(Type → α),
|
||
mvar1 ← mk_meta_var mvar_type,
|
||
alpha ← to_expr ```(α),
|
||
t ← to_expr ```(a),
|
||
unify (mvar1 alpha) t semireducible tt, -- should work
|
||
exact mvar1
|