Commit graph

16333 commits

Author SHA1 Message Date
Leonardo de Moura
45d09d3044 fix(library/compiler/ir): bug at LLNF -> IR 2019-05-01 17:38:44 -07:00
Leonardo de Moura
ed5e461130 feat(library/init/lean/compiler/ir): add maxVar 2019-05-01 17:38:44 -07:00
Leonardo de Moura
2614b95a8b refactor(library/init/lean/compiler/ir): use Nat instead of Name for local vars 2019-05-01 17:38:44 -07:00
Leonardo de Moura
fa0b4bff40 chore(tests/playground/parser/syntax): fix experiment 2019-04-30 18:06:03 -07:00
Leonardo de Moura
0c9fa13763 feat(library/init/lean/compiler): convert LLNF into Lean IR 2019-04-30 17:55:43 -07:00
Leonardo de Moura
d433811c64 test(tests/playground): add "checkpoint" variant for rbmap benchmark
@kha I created a variant of the `rbmap` example where we create a tree
but also save "checkpoints". The idea is to simulate the idiom frequently
used in a backtracking search where we "save" the "context" before each
case split in a "trail stack".
The benchmark has two parameters: the number of nodes to be inserted, and a "frequency" (how often we create a "checkpoint").
The command `rbmap_checkpoint.lean.out n n` behaves like the original
`rbmap` benchmark, and `rbmap_checkpoint.lean.out n 1` creates a
checkpoint after each insertion. The frequency provides a simple way to
control the amount of sharing. We can provide performance numbers for
different frequencies, and show the impact on the `reset/reuse` optimization.

BTW, the performance numbers are much better than I expected. For
example,
`./rbmap_checkpoint.lean.out 1000000 10` is only 30% slower than
`./rbmap_checkpoint.lean.out 1000000 1000000`
although 100k checkpoints were created.

Another good news is that we are faster than Haskell even for
`./rbmap_checkpoint.lean.out 1000000 1`
2019-04-30 10:41:23 -07:00
Leonardo de Moura
952eb0f515 feat(library/compiler): C++ API for Lean IR 2019-04-29 18:23:19 -07:00
Leonardo de Moura
8befa9bea5 chore(stage0): update
Make sure Lean IR primitives are available at Stage0.
2019-04-29 17:16:27 -07:00
Leonardo de Moura
2db7cd158b feat(library/init/lean/compiler/ir): export primitives to C++
Remark: we don't need to expose all of them since the C++ code only
generates code in the Lambda_pure fragment.
2019-04-29 17:10:42 -07:00
Leonardo de Moura
a32fcf33c7 feat(util/array_ref): simple wrapper for creating Lean array objects in C++ 2019-04-29 17:10:35 -07:00
Leonardo de Moura
e0821be132 chore(tests/playground/ir): fix test 2019-04-29 10:50:10 -07:00
Leonardo de Moura
c09df2d8c3 feat(library/init/lean/compiler/ir): use Array instead of List
The idea is to use the same approach we have used at `tests/playground/parser/syntax.lean`
2019-04-29 10:48:33 -07:00
Leonardo de Moura
711fab451b refactor(library/init/data/array): Array.foldl argument order 2019-04-29 10:48:33 -07:00
Leonardo de Moura
63442ebde7 feat(library/init/data/array/basic): add iterate₂ and foldl₂ 2019-04-29 10:48:33 -07:00
Leonardo de Moura
5298841def test(tests/playground/ir): small test 2019-04-29 10:47:51 -07:00
Leonardo de Moura
df84868ab4 feat(library/init/data/array/basic): array helper functions 2019-04-28 10:10:24 -07:00
Leonardo de Moura
dd5fa4626f chore(runtime/object): style 2019-04-28 09:18:54 -07:00
Leonardo de Moura
807c9bff6d refactor(library/init): HasToFormat ==> HasFormat, toFormat ==> format 2019-04-28 09:16:47 -07:00
Leonardo de Moura
79e2abe33f feat(CMakeLists): put configuration options relevant to leanc at config.h 2019-04-27 21:04:41 -07:00
Leonardo de Moura
13d2398fb3 feat(library/init/lean/compiler/ir): formatter 2019-04-27 17:55:27 -07:00
Leonardo de Moura
03f42fda34 refactor(library/init/data/rbmap/basic): use [inline] instead of auxiliary "corpse" 2019-04-27 08:10:26 -07:00
Leonardo de Moura
aefe49d575 test(tests/playground): add new rbmap experiment 2019-04-27 08:02:32 -07:00
Leonardo de Moura
35317139fd chore(library/compiler/util): style 2019-04-26 16:34:22 -07:00
Leonardo de Moura
e1a84d2f2c fix(library/compiler/struct_cases_on): performance problem exposed by badupdate1.lean 2019-04-26 16:30:19 -07:00
Leonardo de Moura
240ca3fc68 test(tests/playground/badupdate1): add test for exposing performance bug at struct_cases_on_fn
```
./run.sh badupdate1.lean 4000
8000
test1 2.12s
8000
test2 1.11ms
```
2019-04-26 15:04:39 -07:00
Leonardo de Moura
3c52183e3c fix(library/compiler/struct_cases_on): bug 2019-04-26 15:04:16 -07:00
Leonardo de Moura
c6d0083456 fear(library/init/data/array/basic): add Array.modify 2019-04-26 14:41:17 -07:00
Leonardo de Moura
1a1105b533 test(tests/playground/lazylist): perf tests 2019-04-26 13:12:39 -07:00
Leonardo de Moura
a5128484a1 test(tests/playground/lazylist): perf tests 2019-04-26 12:05:16 -07:00
Leonardo de Moura
07a68375f5 chore(library/init/lean/compiler/ir): style 2019-04-26 09:15:37 -07:00
Leonardo de Moura
5c7849a869 feat(runtime): eager heap initialization 2019-04-25 18:10:36 -07:00
Leonardo de Moura
9a39eb254a chore(tests/playground): fix tests 2019-04-25 16:48:06 -07:00
Leonardo de Moura
9fb404353e test(tests/playground/lazylist): add cycle 2019-04-25 11:04:04 -07:00
Leonardo de Moura
c8a045d69f test(tests/playground/parser/parser): add HasAndthen and HasOrelse instances 2019-04-24 14:05:45 -07:00
Leonardo de Moura
abaf181495 refactor(core): homogeneous andthen
The motivation is to make sure `andthen` and `orelse` are both
homogeneous.
2019-04-24 14:00:34 -07:00
Leonardo de Moura
69e46881cb feat(library/init/control/alternative): more general HasOrelse class 2019-04-24 14:00:20 -07:00
Leonardo de Moura
865bb8df97 chore(README): update 2019-04-24 11:40:46 -07:00
Leonardo de Moura
014c7e3374 test(tests/playground/parser/parser): "liftable" longestMatch
For lists of size 0, 1 and 2, it avoids the overhead of creating
temporary lists of closures. I measure the overhead with `test1.lean`
and there is no overhead in this case.
`test1.lean` has a test for length = 4, and the overhead is 7%.
We only use longestMatch to implement the Pratt Parser.
The lists should be small. So, the overhead is acceptable.
If it is not. We can add back the `longestMatch` specific for `TermParser`.

cc @kha
2019-04-24 11:23:06 -07:00
Leonardo de Moura
5991337279 test(tests/playground/parser/test1): add test and timeit 2019-04-24 11:20:44 -07:00
Leonardo de Moura
5188adc685 test(tests/playground/parser): add longestMatch and other helper functions 2019-04-23 17:29:38 -07:00
Leonardo de Moura
3d8c3d5789 test(tests/playground/parser/parser): add unicodeSymbol parser 2019-04-23 09:34:41 -07:00
Leonardo de Moura
7c0f3aef5b feat(library/init/data/rbmap/basic): add RBMap.empty 2019-04-23 09:14:54 -07:00
Leonardo de Moura
cac080f504 test(tests/playground/mapVShmap): use {x with ...} notation in the test 2019-04-22 13:42:53 -07:00
Leonardo de Moura
f222dc7cca feat(library/compiler): destructive updates for {x with ...} expressions 2019-04-22 13:35:11 -07:00
Leonardo de Moura
ee0851921b fix(library/compiler/csimp): missing simplification opportunity 2019-04-22 13:15:08 -07:00
Leonardo de Moura
32f41f60d3 feat(runtime/object): add dbgTraceIfShared primitive for debugging RC reuse issues 2019-04-19 16:26:45 -07:00
Leonardo de Moura
363f7dc6f4 test(tests/playground/mapVShmap): add example where hmap is almost 3x faster than map 2019-04-19 14:52:52 -07:00
Leonardo de Moura
e844afb64a test(tests/playground/parser/syntax): propagate lazy macro scopes 2019-04-19 14:52:52 -07:00
Leonardo de Moura
b1503f2c56 perf(library/init/data/array/basic): remove inefficient mforeachAux and add new hmmap and hmap
The `mforeachAux` function was keeping two references to the array
because it was implemented using `miterate a ⟨a, rfl⟩ ...`
Thus, we would have to allocate a new array even if `a` was not shared.

Another issue is that when invoking `x ← f i v`, the array would still
have a reference to `v`, and consequently `RC(v) > 1`, and `f` would not
be able to perform destructive updates to `v` or reuse its memory cell.

Thus, I removed `mforeach` (we only used it to implement `hmap`: the
homogeneous map), and implemented a new `hmap` which makes sure
destructive updates can be performed modulo the issue with float `let`
inwards I described in the previous commit.

@kha I found the problem described in the previous commit when I was
using `Array.hmap`. If we use `Array`s to implement `Syntax` as we discussed,
then a `hmap` that does not prevent destructive updates from happening is
a must-have. Otherwise, any benefit we get from using `Array`s instead
of `List`s is gone.
2019-04-19 14:52:52 -07:00
Leonardo de Moura
b76deb4f0d fix(tests/playground/parser/syntax): another issue with float let inwards
@kha I keep finding problems with the float `let` inwards
transformation. It is always a nasty interaction between this
transformation and the `reset/reuse` insertion procedure.

The example I used in the new comment can be modified to a
`casesOn` with more than one branch (e.g., `Option.casesOn`).
Suppose we wrote
```
let o : Option Nat := Array.index a i in
let a              := Array.update a i none in
Option.casesOn o
  none
  (fun n, some (Array.update a i (some (n + 1))))
```
In the example above, the compiler will float
`a := Array.update a i none` inwards.
```
let o : Option Nat := Array.index a i in
Option.casesOn o
  none
  (fun n,
   let a := Array.update a i none in
   some (Array.update a i (some (n + 1))))
```
Then, adding reset/reuse:
```
let o : Option Nat := Array.index a i in
Option.casesOn o
  none
  (fun n,
   let o := reset o in
   let a := Array.update a i none in
   let n := n + 1 in
   let o := reuse o (some n)
   some (Array.update a i o))
```
Similarly to the example in the new comment, the `reset o` will fail since
the array `a` would still have a reference to `o`.

Remarks:
- Haskell also implements float `let` inwards.
- I am not sure how important the float `let` inward transformation is.
- I can see other nasty interactions after we implement user-defined
  simplification rules. For example, I guess many users would find the
  following lemma to be a good rewriting rule:
  ```
  (Array.update (Array.update a i v) i w) = (Array.update a i w)
  ```
  However, if we use this lemma in the example above, then `Array.update a i none` will be eliminated,
  and `reset o` will fail.
2019-04-19 14:52:52 -07:00