Commit graph

10293 commits

Author SHA1 Message Date
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
04caf5af42 chore(library/derive_attribute): remove unnecessary #includes 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
a5f55300ef feat(library/constants): add uint constants 2018-10-01 14:17:11 -07:00
Leonardo de Moura
3a4acbee9e chore(library/init/data/string): remove string_imp
We will use the (to be implemented) `opaque` keyword
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
751cdd7c42 feat(kernel/type_checker): avoid unnecessary lambdas 2018-09-29 17:24:49 -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
Sebastian Ullrich
a9d5386b00 fix(library/vm/vm_string): fix iterator.extract 2018-09-28 13:08:24 -07:00
Sebastian Ullrich
6cbb77c068 fix(frontends/lean/elaborator): node!: fix view code of try block 2018-09-28 13:08:24 -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
c746783c0d fix(frontends/lean/pp): bug when pretty printing kernel projections 2018-09-27 17:09: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
7a5d0dd65b fix(library/num): to_num should support the new nat literals supported in the kernel 2018-09-27 11:13:50 -07:00
Sebastian Ullrich
e661aaeacf refactor(library/init/lean/parser): store registered parsers in configs, use config hierarchy to avoid mutually recursive types
And other refactorings along the way
2018-09-27 10:05:10 -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
ae81ac2768 chore(frontends/lean): remove parameter command from old parser
We still have a lot of leftover code, but it is not worth removing it
since we will delete the old parser.
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
Leonardo de Moura
25780c6daf fix(library/compiler/csimp): never create join points for floating cases from application 2018-09-25 19:34:29 -07:00
Leonardo de Moura
32888b45a8 chore(library/compiler/csimp): remove leftover 2018-09-25 19:34:29 -07:00
Leonardo de Moura
8613255ff2 chore(library/compiler/csimp): add comment 2018-09-25 19:34:29 -07:00
Leonardo de Moura
6b6b6eb96f feat(library/compiler/csimp): improve float_cases_on 2018-09-25 19:34:29 -07:00
Leonardo de Moura
c9cb576c9b feat(library/compiler/csimp): float cases from application when visiting application 2018-09-25 19:34:29 -07:00