Commit graph

49 commits

Author SHA1 Message Date
Leonardo de Moura
ae30b16f0d fix(library/compiler/lcnf): nat.zero ==> literal 2018-11-01 11:59:17 -07:00
Leonardo de Moura
be0b4c998f fix(library/compiler/lcnf): avoid unnecessary let-decl 2018-10-10 17:33:57 -07:00
Leonardo de Moura
256112be5b chore(library/compiler/lcnf): disable lambda eta-expansion during LCNF conversion
We should do it at `csimp`
2018-10-09 15:25:57 -07:00
Leonardo de Moura
b1f98e8f38 feat(library/compiler/lcnf): eta expand lambdas 2018-10-05 17:30:27 -07:00
Leonardo de Moura
6b8008a222 feat(library/compiler): new compiler entry point (skeleton) 2018-10-05 17:30:27 -07:00
Leonardo de Moura
e89e0075a5 fix(library/compiler/lcnf): do not expand projections of builtin types 2018-10-02 18:56:13 -07:00
Leonardo de Moura
c3569dc72d feat(kernel): store structure name in proj-expressions 2018-10-02 09:23:11 -07:00
Leonardo de Moura
0279cb0766 fix(library/compiler/lcnf): must process constants too 2018-10-01 11:41:57 -07:00
Leonardo de Moura
2c4139d5e5 feat(library/compiler): eta expand quot primitives, add support for eq.rec_on 2018-09-30 08:24:18 -07:00
Leonardo de Moura
86d5ccf8f5 feat(library/compiler/lcnf): nat literals 2018-09-29 16:52:25 -07:00
Leonardo de Moura
5c2286f3c1 refactor(library/compiler): we preserve type information, but we do not preserve type correctness
The compiler applies transformations `t ==> s` where `t` and `s` are
only provably equal, but not definitionally equal. Moreover, in
dependent type theory `C[t]` may be type correct, but `C[s]` is not
when `t` is provably equal to `s`, but not definitionally equal.
Consider the following example:
```
fun n : nat,
  let v : nat      := 0+n in
  let b : bv (0+n) := bv.mk v in
  b
```
If we replace the first `0+n` with `n`, we produce the type incorrect
term
```
fun n : nat,
  let v : nat      := n in
  let b : bv (0+n) := bv.mk v in
  b
```
This is incorrect because `b : bv (0+n)` and `bv.mk v : bv n`, and
`0+n` is not definitionally equal to `n`.

We considered two approaches to address this problem:
1- A relaxed type checker (see deleted file `ctype_checker.cpp`).
This approach does not solve the problem, see example in the end
of the commit.

2- Introduce `lc_cast`-applications to "fix" type problems.  However,
it seems it is too expensive to detect all places that require a
`lc_ast` application. We did that in a few places, but there is major
omission: when we simplify `x : t := v` to `x : t := w` (like in the
example above), we did not find an efficient way to repair all
affected places. We have implemented the function `replace_fvar_with`,
but we would have to execute after each `x : t := v` ==> `x : t := w`
where `v` is not definitionally equal to `w`. We considered grouping
many `replace_fvar_with` together, but it would still be very
expensive. Basically, for any occurrence of `x` we would have to check
whether the resulting type changed or not. Another issue is that the
restrictions considered at `replace_fvar_with` seem to restrictive:
for example `x` cannot occur in lambda/let-decl types. This happens
very frequently in code that uses types such as `decidable p`.
Remark: note that the Lean3 simplifier does not have support for
simplyfing let-decls for this reason. It offers only two options:
expand the `let`, or skip it.

So, this commit gives up the idea of ensuring that each compiler step
produces a type correct Lean term. That is, we preserve type
information, but we do not guarantee the terms are type correct after
we apply compiler transformations.

Here are examples that demonstrate the `ctype_checker` approach does
not work.
```
def C : bool → Type → Type
| tt α := nat × α
| ff α := string × α

def ex  (α β : Type) (x : nat × α) (h₂ : α = β) : nat × β  :=
let f : Π (b : bool) (h₁ : b = tt) (α β : Type) (x : C b α) (h₂ : α = β), nat × β
      := λ (b : bool) (h₁ : b = tt) (α β : Type) (x : C b α) (h₂ : α = β),
         let x₁ : C b β := @eq.ndrec Type α  (λ z : Type, C b z) x β h₂ in
         @eq.ndrec bool b (λ z : bool, C z β) x₁ tt h₁
in f tt rfl α β x h₂
```
Now, suppose we want to put in LCNF. Then, we have to decide whether
each `eq.ndrec` will become a cast or not. Now, suppose we use the
compiler type checker `is_def_eq`.
Then, the first `eq.ndrec` application is `@eq.ndrec Type α  (λ z :
Type, C b z) x β h₂`, and we have that `x : C b α` and the expected
type is `C b β`, both types are stuck since they reduce to
`bool.cases_on b (string × α) (nat × α)` and  `bool.cases_on b (string
× β) (nat × β)` respectively. Thus, they are considered definitionally
equal, and we do not introduce a cast.

The second `eq.ndrec` application is
`@eq.ndrec bool b (λ z : bool, C z β) x₁ tt h₁`, and we have
`x₁ : C b β` and the expected type is `nat × β`, again they are definitionally equal since `C b β`.
Thus, in LCNF, the example above would be:
```
def ex  (α β : Type) (x : nat × α) (h₂ : α = β) : nat × β  :=
let f : Π (b : bool) (h₁ : b = tt) (α β : Type) (x : C b α) (h₂ : α = β), nat × β
      := λ (b : bool) (h₁ : b = tt) (α β : Type) (x : C b α) (h₂ : α = β), x
in f tt rfl α β x h₂
```

The compiler type checker (`ctype_checker`) would say this is a type correct term.
Now, suppose we reduce `f tt rfl α β x h₂` using `csimp`, this term
would reduce to  `x`.
Then, `f` is eliminated since it is not used anymore and we have the new simplified term
```
def ex  (α β : Type) (x : nat × α) (h₂ : α = β) : nat × β  := x
```
`ctype_checker` will report it to be type incorrect. Since, `x : nat × α`
and the result type is `nat × β`, and both are not stuck.
This example shows that by applying simple reduction rules (zeta/beta
in the example above) we can transform a type correct term into a type
incorrect one.

The type `any` is also problematic.  Consider the following example.
```
def ex (x : nat) : real :=
let f : any -> real := fun z, z in
f x
```
It is type correct. If we apply `csimp`, we will get.
```
def ex (x : nat) : real := x
```
which is type incorrect. Again, reduction may transform a type correct term into a type incorrect one.
Note that, I am not using anything fancy here. We are just treating
`any` as definitionally equal to any type.
2018-09-29 12:50:53 -07:00
Leonardo de Moura
dd046b0e0a feat(library/init/core): mark id_rhs as [macro_inline] 2018-09-23 19:27:06 -07:00
Leonardo de Moura
c75db3bfc6 feat(library/compiler): unfold [macro_definition] before LCNF/ANF conversion 2018-09-23 19:27:06 -07:00
Leonardo de Moura
7cfd3b4129 feat(library/compiler/lcnf): modify lcnf format
We should not require the body of a let-decl to be atomic.
2018-09-21 10:59:46 -07:00
Leonardo de Moura
1534f17a89 feat(library/compiler/lcnf): add better support for complete-transition used in the equation compiler and x@ patterns 2018-09-20 21:38:57 -07:00
Leonardo de Moura
f556e0947b fix(library/compiler/lcnf): bug, minor premise must have a lambda for each field in LCNF 2018-09-20 21:38:57 -07:00
Leonardo de Moura
e55b65ad78 chore(library/compiler/lcnf): make it clear when we create the let-expr 2018-09-20 15:33:57 -07:00
Leonardo de Moura
39d9a709d5 feat(library/compiler): improve simplification 2018-09-18 14:51:58 -07:00
Leonardo de Moura
4f53e505b0 fix(library/compiler): we need to unfold auxiliary nested _match applications eagerly 2018-09-18 14:17:37 -07:00
Leonardo de Moura
ff725b8329 feat(library/compiler): simplify cheap beta reduction
The LCNF format contained may `let`-declarations of the form
```
x : (fun y, c) a := t
```
where `c` does not depend on `y`.
We reduce them to
```
x : c := t
```
2018-09-17 19:58:54 -07:00
Leonardo de Moura
faf4561723 feat(library/compiler/lcnf): expand nested f._match_<idx> applications at to_lcnf 2018-09-17 13:41:03 -07:00
Leonardo de Moura
ca176259f4 feat(library/compiler): treat f._meta_rec applications as f applications in the new compiler stack 2018-09-17 09:56:06 -07:00
Leonardo de Moura
33821f399c chore(library/compiler): lc_util.* ==> util.* 2018-09-17 08:50:50 -07:00
Leonardo de Moura
1cc60fdeac feat(library/compiler): add helper functions 2018-09-14 15:41:01 -07:00
Leonardo de Moura
1c0ff0db72 fix(library/compiler/lcnf): make sure lc_cast applications are not overapplied 2018-09-14 15:08:35 -07:00
Leonardo de Moura
24de0e95f1 feat(library/compiler/lcnf): make test complete 2018-09-14 14:45:51 -07:00
Leonardo de Moura
75b494e33d feat(library/compiler): use new constructor info 2018-09-14 13:51:53 -07:00
Leonardo de Moura
a2c5daeded feat(library/compiler/lcnf): modify LCNF format
Now, the body of a let-expression is atomic.
2018-09-14 13:26:24 -07:00
Leonardo de Moura
eb2d8543f7 chore(library/compiler/lcnf): add comment 2018-09-14 12:03:17 -07:00
Leonardo de Moura
4cca030251 chore(library/compiler/lcnf): do not beta reduce at to_lcnf 2018-09-13 18:13:53 -07:00
Leonardo de Moura
b8dceda9b7 chore(kernel): type_checker::context ==> type_checker::state 2018-09-13 14:06:57 -07:00
Leonardo de Moura
c02e2d3b56 feat(library/compiler/lcnf): split cases followed by application 2018-09-13 12:57:08 -07:00
Leonardo de Moura
c49ad19736 refactor(kernel/type_checker): type_checker::cache ==> type_checker::context
We also move `environment` and `name_generator` to
`type_checker::context`. Reason: the cache assumes the environment did
not change. The (cache) correctness relies on the fact that we don't
reuse free variable identifiers.
2018-09-12 20:34:30 -07:00
Leonardo de Moura
7f496f43f1 fix(library/compiler/lcnf): it was not erasing proofs that start with Pi 2018-09-12 18:26:23 -07:00
Leonardo de Moura
379c06faf4 fix(library/compiler/lcnf): avoid trivial let-decls 2018-09-12 18:24:12 -07:00
Leonardo de Moura
bfb3ffbc79 feat(library/compiler/lcnf): safe beta reduction 2018-09-12 14:51:19 -07:00
Leonardo de Moura
112f183be4 feat(library/compiler/lcnf): eliminate false.cases_on and eq.cases_on 2018-09-12 14:27:01 -07:00
Leonardo de Moura
1e5f0a91f1 feat(library/compiler/lcnf): eliminate and.rec and and.cases_on 2018-09-12 14:21:28 -07:00
Leonardo de Moura
b1fb4416f3 feat(library/compiler/lcnf): make sure constructor applications are fully applied 2018-09-12 14:04:24 -07:00
Leonardo de Moura
4058276a82 feat(library/compiler/lcnf): eliminate false.rec 2018-09-12 13:55:32 -07:00
Leonardo de Moura
cfdc331ecb feat(library/compiler/lcnf): replace eq.rec and eq.ndrec applications with lc_cast 2018-09-12 11:00:34 -07:00
Leonardo de Moura
c526670e6f feat(library/compiler/lcnf): eliminate id_rhs even if it is partially applied 2018-09-12 10:45:23 -07:00
Leonardo de Moura
2d6582e67c fix(library/compiler/lcnf): dumb mistake, Pi case is not reachable 2018-09-12 10:40:09 -07:00
Leonardo de Moura
ec1809de74 fix(library/compiler/lcnf): restore cache 2018-09-12 10:40:09 -07:00
Leonardo de Moura
ec92653d93 feat(library/compiler/lcnf): do not create aux let-decl for lc_proof-applications 2018-09-12 10:40:09 -07:00
Leonardo de Moura
d5d926b0ef feat(library/compiler/lcnf): eliminate no_confusion 2018-09-12 10:40:09 -07:00
Leonardo de Moura
8ee10e202f chore(library/compiler/lcnf): use _x_<idx> instead of _x.<idx>
This is a temporary change while we debug the new compiler.
2018-09-11 18:10:10 -07:00
Leonardo de Moura
72e99ea3ee fix(library/compiler/lcnf): apply_beta takes arguments in reverse order 2018-09-11 18:10:10 -07:00
Leonardo de Moura
9b21287a3e feat(library/compiler/lcnf): add lean compiler normal form 2018-09-11 18:10:10 -07:00