Commit graph

371 commits

Author SHA1 Message Date
Leonardo de Moura
adfc0e28ea feat(library/compiler/erase_irrelevant): missing is_irrelevant checks, missing terms being visited, mixing erased with non-erased terms 2018-10-03 16:22:44 -07:00
Leonardo de Moura
826e63873e feat(library/compiler/preprocess): use new compiler stack that has already been implemented 2018-10-03 13:24:01 -07:00
Leonardo de Moura
1b95cbeca1 fix(library/compiler/simp_inductive): adjust kernel projections 2018-10-02 18:56:13 -07:00
Leonardo de Moura
c9aab6ef50 feat(library/compiler): register noinline attribute 2018-10-02 18:56:13 -07:00
Leonardo de Moura
fa906c6bda fix(library/compiler/lambda_lifting): use user_name 2018-10-02 18:56:13 -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
cd8dc8670d fix(library/compiler/erase_irrelevant): visit_constant 2018-10-02 18:56:13 -07:00
Leonardo de Moura
49425aa80c fix(library/compiler/erase_irrelevant): assertion violation 2018-10-02 18:56:13 -07:00
Leonardo de Moura
24bd5782e0 fix(library/compiler/erase_irrelevant): make sure lambda that return irrelevant data is marked as irrelevant 2018-10-02 18:56:13 -07:00
Leonardo de Moura
85c58e8f0e feat(library/compiler): add support for string literals in the old VM 2018-10-02 18:56:13 -07:00
Leonardo de Moura
dc937281b3 chore(library/init/string): remove string.iterator_imp 2018-10-02 13:46:01 -07:00
Leonardo de Moura
fd46adb7b3 fix(library/compiler/erase_irrelevant): minor issues 2018-10-02 13:36:48 -07:00
Leonardo de Moura
20e7edd4ac feat(library/compiler): erase trivial structures and flat cases on structures 2018-10-02 11:05:15 -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
c05e7a31a3 chore(library/compiler): add is_runtime_scalar_type and is_runtime_builtin_type 2018-10-02 09:03:53 -07:00
Leonardo de Moura
fbe702510d fix(library/compiler/csimp): missing projection of instance simplification 2018-10-01 17:23:29 -07:00
Leonardo de Moura
25b45d6f9e feat(library/compiler): add erase_irrelevant transformation to new compiler stack 2018-10-01 17:06:56 -07:00
Leonardo de Moura
efa77c2a5b fix(library/compiler/inliner): bug in the old compiler
The bug was being masked by the `elim_recursors` transformation.
When this transformation was used, the bug would manifest itself as a
performance bug.
2018-10-01 14:17:11 -07:00
Leonardo de Moura
e466ecd263 chore(library/compiler/lambda_lifting): fix debug mode compilation errors 2018-10-01 14:17:11 -07:00
Leonardo de Moura
b4c2861939 refactor(library/compiler): rename "erasure normal form" functions 2018-10-01 14:17:11 -07:00
Leonardo de Moura
81e9e95570 chore(library/compiler): erase_irrelevant ==> old_erase_irrelevant 2018-10-01 14:17: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
70041bf43f feat(library/compiler/vm_compiler): add option codegen 2018-10-01 11:41:57 -07:00
Leonardo de Moura
990fbe3c30 feat(library/compiler): provide options to vm_compile 2018-09-30 08:50:40 -07:00
Leonardo de Moura
a17b95acc7 feat(library/compiler/erase_irrelevant): add support for lc_unreachable 2018-09-30 08:25:06 -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
cdc0a5ac29 fix(library/compiler/vm_compiler): add support for kernel projections 2018-09-29 17:24:11 -07:00
Leonardo de Moura
86d5ccf8f5 feat(library/compiler/lcnf): nat literals 2018-09-29 16:52:25 -07:00
Leonardo de Moura
54b4908349 chore(library/compiler): remove step from old compiler 2018-09-29 16:48:24 -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
9bfb8a9782 chore(library/compiler/ctype_checker): refine comment 2018-09-28 18:27:40 -07:00
Leonardo de Moura
c432f6d056 feat(library/compiler/ctype_checker): add is_stuck_type 2018-09-28 16:13:33 -07:00
Leonardo de Moura
d8af3dc906 feat(library/compiler): add ctype_checker
It is just a big wishlist at this point.
The goal is to use it instead of the kernel type_checker.
2018-09-28 15:37:41 -07:00
Leonardo de Moura
1477036b36 fix(library/compiler/csimp): we may have partially applied cases_on applications in the computationally irrelevant part 2018-09-28 08:32:10 -07:00
Leonardo de Moura
2d8d0d5a6c feat(library/compiler): inline small functions and join points 2018-09-27 18:21:31 -07:00
Leonardo de Moura
6786b2bcc8 fix(library/compiler/csimp): bug at join point preservation code 2018-09-27 17:48:02 -07:00
Leonardo de Moura
bd97f67f28 feat(library/compiler/csimp): improve heuristic for deciding whether we should create join point or not 2018-09-27 16:40:57 -07:00
Leonardo de Moura
4dd0b4079b fix(library/compiler/csimp): bug at mk_new_join_point 2018-09-27 16:40:57 -07:00
Leonardo de Moura
20e98cbcff feat(library/compiler/csimp): remove bad join-point creation 2018-09-27 14:56:09 -07:00
Leonardo de Moura
d880b1c640 feat(library/compiler): add is_float_cases_on_worthwhile predicate and cleanup 2018-09-27 13:12:20 -07:00
Leonardo de Moura
2c2103711c feat(library/compiler/csimp): we may be able to unfold join point 2018-09-26 18:01:57 -07:00
Leonardo de Moura
ccd73701cb feat(library/compiler/csimp): preserve joint points 2018-09-26 17:54:11 -07:00
Leonardo de Moura
f3552f70f6 feat(library/compiler/csimp): simplify code 2018-09-26 17:54:10 -07:00
Leonardo de Moura
e7b99d5a07 fix(library/compiler/csimp): bug at split_entries 2018-09-26 17:54:10 -07:00
Leonardo de Moura
6578b2b6ce chore(library/compiler/csimp): cleanup 2018-09-26 17:54:10 -07:00
Leonardo de Moura
33322d44ee chore(library/compiler/csimp): remove dead code 2018-09-26 13:46:27 -07:00
Leonardo de Moura
b324aa4b33 feat(library/compiler/csimp): do not inline partial applications 2018-09-26 09:05:28 -07:00
Leonardo de Moura
21b8199bc4 feat(library/compiler/util): do not consider constructors to be cost zero 2018-09-26 08:48:06 -07:00
Leonardo de Moura
7fed0b5cb0 fix(library/compiler/csimp): bug in the join point generation 2018-09-26 08:47:49 -07:00
Leonardo de Moura
15222a79a0 chore(library/compiler/csimp): display "code size" 2018-09-25 19:34:29 -07:00