Commit graph

5086 commits

Author SHA1 Message Date
Leonardo de Moura
6b8008a222 feat(library/compiler): new compiler entry point (skeleton) 2018-10-05 17:30:27 -07:00
Leonardo de Moura
1d1efdd5f3 chore(library/compiler/preprocess): remove dead global 2018-10-05 17:30:27 -07:00
Leonardo de Moura
a21dac4384 chore(library/compiler/vm_compiler): remove option 2018-10-05 17:30:27 -07:00
Leonardo de Moura
135a8d7508 chore(library/compiler): remove old compiler steps that have already been replaced 2018-10-05 17:30:27 -07:00
Leonardo de Moura
e18af852c8 feat(library/compiler): add code specialization skeleton 2018-10-05 17:30:27 -07:00
Leonardo de Moura
66fe6463fe fix(library/compiler/csimp): missing mk_let 2018-10-04 15:25:03 -07:00
Leonardo de Moura
78842d4b9b fix(library/compiler/util): macro_inline was ignoring constants 2018-10-04 15:25:03 -07:00
Leonardo de Moura
08425c456a chore(library/compiler/preprocess): remove dead code 2018-10-03 16:22:44 -07:00
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
cf5141f8ad chore(library/vm/vm): fix style 2018-10-03 13:25:54 -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
13f0a7cd81 chore(frontends/lean, library/vm): save some debugging help code 2018-10-03 13:20:24 -07:00
Leonardo de Moura
9f161e6968 fix(library,kernel): the new proj_sname field must be taken into account during comparisons
`proj_sname` is not just for enabling better pretty printing. It is
necessary in the compiler when type information is lost, and we can't
infer the type of a `proj`-term argument (field `proj_expr`).
2018-10-03 13:11:46 -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
3ac6eab393 chore(library/vm): remove vm_list 2018-10-02 08:44:05 -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
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
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
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