Add examples that demonstrate limitations of the current elaborator. The new design, we are working on, will be able to solve them.
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
33c4b44b2b
commit
6bb9fc859e
3 changed files with 72 additions and 0 deletions
24
tests/lean/bad/t1.lean
Normal file
24
tests/lean/bad/t1.lean
Normal file
|
@ -0,0 +1,24 @@
|
|||
Variable g : Pi A : Type, A -> A.
|
||||
Variables a b : Int
|
||||
(*
|
||||
The following example demonstrates a limitation in the current elaborator.
|
||||
The current elaborator decides overloads before filling holes.
|
||||
The symbol '>' is overloaded. The possible overloads are:
|
||||
Nat::lt Nat -> Nat -> Nat
|
||||
Int::lt Int -> Int -> Int
|
||||
Real::lt Real -> Real -> Real
|
||||
The type of (g _ a) is not available when the overload is decided, and
|
||||
0 has type Nat. Then, the overload resolver selects
|
||||
Nat::lt Nat -> Nat -> Nat
|
||||
Now, when we fill the holes, (g _ a) is elaborated to (g Int a) which
|
||||
has type Int, and we fail.
|
||||
If the hole elaborator and overload resolver are executed simultaneously,
|
||||
we would get the fully elaborated term:
|
||||
|
||||
Int::le (g Int a) (nat_to_int 0)
|
||||
*)
|
||||
Axiom H1 : g _ a > 0
|
||||
(*
|
||||
One workaround consists in manually providing the coercion.
|
||||
*)
|
||||
Axiom H1 : g _ a > (nat_to_int 0)
|
36
tests/lean/bad/t2.lean
Normal file
36
tests/lean/bad/t2.lean
Normal file
|
@ -0,0 +1,36 @@
|
|||
Variable list : Type -> Type
|
||||
Variable nil {A : Type} : list A
|
||||
Variable cons {A : Type} (head : A) (tail : list A) : list A
|
||||
Definition n1 : list Int := cons (nat_to_int 10) nil
|
||||
Definition n2 : list Nat := cons 10 nil
|
||||
(*
|
||||
The following example demonstrates that the expected type (list Int)
|
||||
does not influece whether coercions are used or not.
|
||||
*)
|
||||
Definition n3 : list Int := cons 10 nil
|
||||
|
||||
(*
|
||||
Here are some workarounds for the example above.
|
||||
The 'let' construct is one of the main tools for providing
|
||||
hints.
|
||||
*)
|
||||
Definition n3a : list Int :=
|
||||
let a : Int := 10
|
||||
in cons a nil
|
||||
|
||||
(* Solution b: we manually provide the coercion *)
|
||||
Definition n3b : list Int := cons (nat_to_int 10) nil
|
||||
|
||||
(* The folowing example works *)
|
||||
Definition n4 : list Int := nil
|
||||
|
||||
(*
|
||||
The following example demonstrates that we do not do type inference.
|
||||
In the current implementation, we first elaborate the type and
|
||||
then the body.
|
||||
*)
|
||||
Definition n5 : _ := cons 10 nil
|
||||
|
||||
Set pp::coercion true
|
||||
Set pp::implicit true
|
||||
Show Environment 1.
|
12
tests/lean/bad/t3.lean
Normal file
12
tests/lean/bad/t3.lean
Normal file
|
@ -0,0 +1,12 @@
|
|||
Variable list : Type -> Type
|
||||
Variable nil {A : Type} : list A
|
||||
Variable cons {A : Type} (head : A) (tail : list A) : list A
|
||||
Variables a b : Int
|
||||
Variables n m : Nat
|
||||
(*
|
||||
Here are other examples showing that coercions and implicit arguments
|
||||
do not "interact well with each other" in the current implementation.
|
||||
*)
|
||||
Definition l1 : list Int := cons a (cons b (cons n nil))
|
||||
Definition l2 : list Int := cons a (cons n (cons b nil))
|
||||
Check cons a (cons b (cons n nil))
|
Loading…
Reference in a new issue