Commit graph

369 commits

Author SHA1 Message Date
Leonardo de Moura
0c785f8ab7 feat(library/init/data): add instances for has_repr (id A) and has_to_string (id A) 2018-05-10 17:37:57 -07:00
Leonardo de Moura
224fdc7a78 refactor(library/init/lean/ir): platform dependent IR
Motivation: in 64-bit machines, we can store boxed uint32 values as a
tagged pointer. In 32-bit machines, we need to allocated an object (like
Haskell) to store the uint32 value. So, the generated bytecode is quite
different in each platform.

This change also allow us to simplify the IR. Example: we don't need the
type `sizet` anymore.

Impact: To be able to bootstrap in both platforms,
we will have to store two versions of the generated code: 32 and 64
versions. In principle, we only need to store the 64-bit version,
and use cross-compilation to build the 32-bit version.
2018-05-10 13:15:02 -07:00
Leonardo de Moura
63bddd56d6 feat(library/init/data/rbmap,library/init/data/rbtree): add mfold and mfor for rbtree/rbmap 2018-05-09 15:38:57 -07:00
Leonardo de Moura
d85c30fde1 perf(library/init/data): mark usize, uint16, uint32 and uint64 as [irreducible]
Without these annotations, Lean will timeout when trying to synthesize
the type class instance `decidable_eq uint32`. The type class resolution
problem will produce the unification problem:
```
decidable (@eq uint32 a b) =?= decidable (@eq usize ?x ?y)
```
which Lean tries to solve by assigning `?x := a`.
During the assignment, the types of `?x` and `a` are unified with "full
force". Thus, we get the constraint
```
usize_sz =?= uint32_sz
```
which will take forever to be solved when peforming the computation in
unary arithmetic.

Remark: this commit also makes sure that `type_context` will not unfold
irreducible definitions when trying to unify/match the types.

The new test `type_class_performance1.lean` exposes the problem fixed
by this commit.
2018-05-07 18:07:04 -07:00
Leonardo de Moura
5b89f69e36 chore(library/init/data/dlist): add @[inline] 2018-05-07 18:07:04 -07:00
Leonardo de Moura
89b4bb7210 feat(library/init/data/hashable): add hashable nat instance 2018-05-06 07:53:29 -07:00
Leonardo de Moura
3079d2d007 feat(library/init/lean/name): add hashable instance 2018-05-06 07:49:17 -07:00
Leonardo de Moura
162f817fa3 feat(library/init/data/hashable): add builtin string hash 2018-05-06 07:28:05 -07:00
Leonardo de Moura
e64cb10ded feat(library/init): add hashable type class 2018-05-05 20:48:57 -07:00
Leonardo de Moura
d5fe509c36 chore(*): remove end after each match-expression
`end` is not optional anymore
2018-05-04 11:30:06 -07:00
Leonardo de Moura
752e0a134e chore(library/init/data/nat/basic): cleanup 2018-05-04 11:30:06 -07:00
Leonardo de Moura
11a8a7c4f3 feat(library/init): use usize instead of uint32 in the low level array access primitives 2018-05-04 10:40:14 -07:00
Leonardo de Moura
af4f831a9f feat(library/init/data/hashmap): hash function produces an uint32 instead of nat
Most efficient hash functions use uint32/uint64 and produce values
that do not fit in out small nat representation. Thus, GMP big numbers
would have to be created.
2018-05-03 17:56:10 -07:00
Leonardo de Moura
ff7e691d66 feat(library/vm): add support for system.platform.nbits in the VM 2018-05-03 15:54:54 -07:00
Leonardo de Moura
acade175b6 feat(library/init/data/array): store dimension in the array
The array dimension is now stored inside the array.
The main motivation is that it reflects the actual runtime implementation.
We need to store the array size to be able to GC it.
So, it feels silly to have the array size stored in each array object,
but we cannot use this information.
For example, in the `hashmap` we implemented the bucket array using
`array`, and we store the `size` of the array.
Same for the Lean3 `buffer` object.
The `buffer` object doesn't even need to exist.
The actual `array` implementation is the `buffer`
2018-05-03 15:43:03 -07:00
Leonardo de Moura
668d198991 feat(library/init/data/usize): add usize 2018-05-03 15:43:00 -07:00
Leonardo de Moura
732d638bb8 chore(library/init/data/array/lemmas): remove array theorems 2018-05-03 15:38:42 -07:00
Leonardo de Moura
9aa459c7e1 feat(library/init/data/nat/basic): add auxiliary power theorems 2018-05-03 11:23:59 -07:00
Leonardo de Moura
c135d0ae61 chore(library/init/data/uint): cleanup 2018-05-03 10:42:50 -07:00
Leonardo de Moura
f2df67053f feat(library/init/data/dlist): add dlist back without tactic framework dependency 2018-05-02 12:36:31 -07:00
Leonardo de Moura
45694ae44a fix(library/init/data/nat/basic): performance problem
Before this commit, given `x n : nat` the expression
```
to_bool (n <= x)
```
where `n` is a numeral <= 1024 was being elaborated as
```
@decidable.to_bool (@has_le.le.{0} nat nat.has_le n x) (nat.decidable_lt n' x)
```
where `n'` denotes the numeral `n-1`
Example:
```
to_bool (800 <= x)
```
was elaborated as
```
@decidable.to_bool (@has_le.le.{0} nat nat.has_le 800 x) (nat.decidable_lt 799 x)
```

Reason: `nat.lt` and `nat.le` were reducible. The module `type_context`
has support for solving "offset constraints" for small numerals.
These constraints include:
- `succ ?x =?= n`  ===> `?x := n - 1`

For elaborating `to_bool (800 <= x)`, we need to synthesize
```
decidable (@has_le.le.{0} nat nat.has_le 800 x)
```
using type class resolution.

The instance `nat.decidable_lt` is tried before `nat.decidable_le`. For
this instance, we need to solve the unification problem.
```
decidable (@has_lt.lt.{0} nat nat.has_lt ?n ?x) =?= decidable (@has_le.le.{0} nat nat.has_le 800 x)
```
which reduces to:
```
nat.less_than_or_equal (succ ?n) ?x =?= nat.less_than_or_equal 800 x
```
because `nat.le` and `nat.lt` are marked as `[reducible]`.
This constraint reduces to
```
succ ?n =?= 800
```
which is solved using the offset constraint support as
```
?n := 799
```

The kernel does not have support for offset constraints, and may take
a considerable amount of time to check that `succ 799` is definitionally
equal to `800`. This is particularly expensive when trust level 0 is
used.
It was taking almost 1 minute to execute the leanchecker test before
this commit because we add the new predicates for checking which
characters can be used in a Lean identifier.

This commit fixes the problem by removing the annotation `[reducible]`
from `nat.lt` and `nat.le`. This performance issue may be triggered
by any reducible instance that may create offset constraints during
type class resolution.

cc @kha
2018-05-01 11:50:54 -07:00
Leonardo de Moura
5a560b6d43 feat(library/init/data): add hashmap
We use the same approach used to define rbtree:
1- Structure with minimal number of invariants, AND
2- well_formed inductive predicate

We can use the well_formed predicate to prove auxiliary invariants later.
Example: the keys stored in every bucket have the correct hash code.

This implementation does not depend on the tactic framework,
and it is not a mess like the one in mathlib.
2018-04-30 18:28:29 -07:00
Leonardo de Moura
50b7efe00d refactor(library/init/data/array/basic): make sure init/data/array/basic does not depend on init.meta 2018-04-30 17:16:45 -07:00
Leonardo de Moura
f20f50254c feat(library/init/data/string/basic): add string.line_column 2018-04-30 15:55:34 -07:00
Leonardo de Moura
62d425073e feat(library/init/data/string/basic): add string.iterator.offset 2018-04-30 15:43:51 -07:00
Leonardo de Moura
4fa43f18dd chore(library/init/data/rbtree,library/init/data/rbmap): remove auto_param dependency
The problem is that `auto_param` is defined in the old `init/meta/name` module,
and we don't want to have `init/meta` dependencies in the `init/lean` modules.
2018-04-30 13:24:13 -07:00
Leonardo de Moura
2cb6af9769 refactor(library/init/control): remove init.meta.name spurious dependency 2018-04-30 11:36:07 -07:00
Leonardo de Moura
75a67ceb29 refactor(library/init): move option.lt 2018-04-30 11:19:38 -07:00
Leonardo de Moura
5787f17138 chore(library/init): merge sigma/lex.lean with wf.lean 2018-04-30 10:04:03 -07:00
Leonardo de Moura
1ab1b07aec chore(library/init/data/sigma/lex): remove tactic framework dependency 2018-04-30 09:55:37 -07:00
Leonardo de Moura
65e3c96b28 chore(library/init): remove sum micro module 2018-04-30 09:25:26 -07:00
Leonardo de Moura
9f18d6545c chore(library/init): remove funext and quot modules
The spaghetti initialization is almost over.
2018-04-30 09:25:26 -07:00
Leonardo de Moura
98a7aab3ac chore(library/init): remove propext micro module 2018-04-30 09:25:26 -07:00
Leonardo de Moura
eae4483d2a chore(library/init): remove setoid micro module 2018-04-30 09:25:26 -07:00
Leonardo de Moura
e2abb4ab25 chore(library/init): remove punit micro module 2018-04-30 09:25:26 -07:00
Leonardo de Moura
2503d6026e chore(library/init): remove prod micro module 2018-04-30 09:25:25 -07:00
Leonardo de Moura
e9d4780ccb chore(library/init): remove subtype micro module 2018-04-30 09:25:25 -07:00
Leonardo de Moura
9efd07d18c chore(library/init): move logic.lean => core.lean 2018-04-30 09:25:25 -07:00
Leonardo de Moura
1289037e56 chore(library/init): cleanup 2018-04-30 09:25:25 -07:00
Leonardo de Moura
6ef4806fca feat(library/init/lean/format): add lean.format 2018-04-29 14:36:49 -07:00
Leonardo de Moura
c9e4c89d9c chore(library/init/meta): remove mk_dec_eq_instance
The tactic mk_dec_eq_instance constructs a function using the brec_on
recursor. The compiler generates horrible code for this kind of
definition. It creates a closure for each recursive call.
Moreover, `brec_on` accumulates all intermediate results.

To generate efficient code, we need to generate a collection of
recursive equations, and then invoke the equation compiler.

cc @kha
2018-04-27 16:13:10 -07:00
Leonardo de Moura
21d9409629 feat(library/init/data): modify unit has_to_string and has_repr instances 2018-04-27 13:39:19 -07:00
Leonardo de Moura
ba633df7e7 chore(library/init/data): add missing instances 2018-04-27 13:39:19 -07:00
Leonardo de Moura
77d3a788e8 refactor(init): init/category ==> init.control 2018-04-27 08:33:08 -07:00
Leonardo de Moura
0af913c99f refactor(library/init/data/string): define decidable_eq string instance earlier 2018-04-27 08:16:14 -07:00
Leonardo de Moura
9e9a0d103f feat(library/vm/vm_string): add fast string.iterator.remaining 2018-04-26 18:03:41 -07:00
Leonardo de Moura
3091ca3441 feat(library/init/data/char): use bool instead of Prop for basic char predicates 2018-04-26 13:46:59 -07:00
Leonardo de Moura
e602ac873a feat(library/init): modify && and || precedence
The idea is to match the precedence used in regular programming
languages, where `x = y || x = z` is parsed as `(x = y) || (x = z)`.

This commit also adds `!x` as notation for `bnot x`
2018-04-26 13:40:57 -07:00
Leonardo de Moura
cd4f196842 chore(library/init/data/option/basic): dead code 2018-04-25 17:19:11 -07:00
Leonardo de Moura
51e0987af2 feat(library/init/data/rbtree): add rbtree.seteq 2018-04-25 16:13:38 -07:00