Compare commits

...

1963 Commits

Author SHA1 Message Date
Leonardo de Moura
035299a30f checkpoint
Failed attempt to construct missing `Repr` instances recursively.
The correct solution is to track the reason for a TC failure.
Or, add support at the TC procedure for generating "missing
instances". That is, when `TC` fails to find global instances for
`Repr Foo`, it tries to invoke the `deriving` handler. It seems a bit crazy.
2022-06-29 14:16:55 -07:00
Leonardo de Moura
e968dfb68c feat: elaborate do notation even when expected type is not available
see issue #1256
2022-06-29 13:30:06 -07:00
Leonardo de Moura
598898a087 fix: fixes #1265 2022-06-29 12:41:14 -07:00
Leonardo de Moura
15e2a7d5b4 feat: report errors an unassigned metavars at #eval
See #1256
2022-06-29 11:53:33 -07:00
Sebastian Ullrich
3ed910a043 refactor: rename AsyncList.asyncTail to delayed
I often found the terminology confusing as it is inconsistent with
`List.tail`
2022-06-29 17:08:15 +02:00
Sebastian Ullrich
ae683af9c2 refactor: merge AsyncList.updateFinishedPrefix/finishedPrefix
We only ever use both of them together, and forgetting to call the first
one first could lead to subtle bugs.
2022-06-29 17:08:15 +02:00
Sebastian Ullrich
c8fb72195b feat: print panic backtraces on Linux 2022-06-29 16:29:35 +02:00
Leonardo de Moura
a888b21bce fix: compiler bug at And.casesOn
Fixes issue reported at https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/.28libc.2B.2Babi.29.20lean.3A.3Aexception.3A.20incomplete.20case/near/287839995
2022-06-29 06:56:17 -07:00
Sebastian Ullrich
10b0eca41f chore: CI: minor 2022-06-29 12:43:01 +02:00
Leonardo de Moura
98b8e300e1 feat: add evalTerm and Meta.evalExpr
These functions were in Mathlib 4.
2022-06-28 19:14:40 -07:00
Leonardo de Moura
fc7c1d1053 chore: remove unnecessary set_option 2022-06-28 17:37:10 -07:00
Leonardo de Moura
87a72e4bbe chore: update stage0 2022-06-28 16:57:11 -07:00
Sebastian Ullrich
80217cfa90 fix: asynchronous head snapshot fallout 2022-06-28 16:54:29 -07:00
Sebastian Ullrich
99f5e94efe feat: MonadExcept.ofExcept 2022-06-28 16:54:29 -07:00
Sebastian Ullrich
c64ac02ffc fix: declModifiers syntax kind 2022-06-28 22:35:13 +02:00
Sebastian Ullrich
a9cc57c81c chore: CI: more cache setup 2022-06-28 22:31:51 +02:00
Sebastian Ullrich
920fa1109b chore: CI: ccache permissions 2022-06-28 18:53:36 +02:00
Sebastian Ullrich
9816331562 chore: clean up bootstrapping cleanup 2022-06-28 16:28:36 +02:00
Sebastian Ullrich
995d92d10e chore: CI: fix ccache cache group 2022-06-28 16:24:10 +02:00
Sebastian Ullrich
8f3fda4777 chore: update stage0 2022-06-28 16:01:43 +02:00
Sebastian Ullrich
77c6f433c7 chore: clean up bootstrapping workarounds 2022-06-28 16:01:07 +02:00
Sebastian Ullrich
74c4437874 chore: CI: simplify Nix setup, bring back macOS 2022-06-28 12:50:19 +02:00
Sebastian Ullrich
5bba20d6a9 refactor: revert toParserDescr signature change 2022-06-28 11:50:59 +02:00
Sebastian Ullrich
89a101e9b8 refactor: remove group(·)s 2022-06-28 11:50:59 +02:00
Sebastian Ullrich
9490328429 chore: update stage0 2022-06-28 11:50:59 +02:00
Sebastian Ullrich
eab64997cd fix: auto-group syntax parsers where necessary 2022-06-28 11:50:59 +02:00
Timo
e49a81bb56 doc: fix typo 2022-06-27 19:48:45 -07:00
Leonardo de Moura
34dc2572f3 fix: make sure OfScientific Float instance is never unfolded during type class resolution
This commit fixes issue reported at
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/deterministic.20timeout/near/287654818

Type class resolution was diverging when trying to synthesize
```lean
 HSub (optParam Float 0.0) (optParam Float 1.0) ?m.472
```
and Lean was diverging while unfolding
```lean
 instance : OfScientific Float where
   ofScientific m s e :=
     if s then
       let s := 64 - m.log2 -- ensure we have 64 bits of mantissa left after division
       let m := (m <<< (3 * e + s)) / 5^e
       Float.ofBinaryScientific m (-4 * e - s)
     else
       Float.ofBinaryScientific (m * 5^e) e
```
was being unfolded.

Anothe potential solution for the problem above is to erase the
`optParam` annotations before performing type class resolution.
2022-06-27 17:40:34 -07:00
Sebastian Ullrich
ca19ce1e6f chore: CI: fix Windows 2022-06-28 00:38:19 +02:00
Sebastian Ullrich
18d2296b1c doc: add typed macros to RELEASES.md 2022-06-27 23:42:13 +02:00
Leonardo de Moura
5901fef43a feat: protected aliases
See message: https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Namespace-based.20overloading.20does.20not.20find.20exports/near/287633118
2022-06-27 13:56:58 -07:00
Sebastian Ullrich
19c2644d88 chore: add more comments 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
544a046678 chore: use Syntax.Level 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
22475b8669 refactor: introduce common TSyntax abbreviations 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
db42874be4 chore: update Lake 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
e47f248161 doc: TSyntax 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
8b4d8b8dc9 feat: TSyntax singleton kind unexpanders 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
6f7ff3b492 chore: remove unnecessary type annotations 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
6af00ff23e chore: changes to placate coercions 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
d9cfda4893 refactor: make more use of quotations
Automatically fixes many TSyntax type errors
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
7043c4ebe7 refactor: mkSimpleDelab 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
0b28f059f6 chore: work around "unknown free variable" bug 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
3a56db2812 chore: fix tests 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
c3585dbbbb chore: raw syntax kind accesses
Sometimes just checking the kind simply is the simplest solution.
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
c2166fc602 chore: work around parameterized parser syntax kinds
We should find a better solution for calling parameterized parsers such
as `matchAlt` than these helper definitions that confuse the antiquotations.
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
d499e67c87 fix: incorrect antiquotation kind annotations
Apparently, none of them led to incorrect syntax trees, but `TSyntax`
still disapproves.
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
6c64b1b20b chore: work around for type inference
It seems type information often flows from the body to the loop
variable, which is problematic with coercions.
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
5e334b3e90 chore: postpone TSyntax adoption for some parts
The namespace `TSyntax.Compat` can be opened for a coercion
`Syntax -> TSyntax k` for any `k`, as otherwise this PR would never be done.
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
fe22d84143 fix: unclear TSyntax breakage 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
86cd656fc6 refactor: adapt raw syntax manipulations to TSyntax
Sometimes there's just no structure to work on
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
498c7a6a97 refactor: remove some unnecessary antiquotation kind annotations
These are just the ones I stumbled upon, there should be a lot more now
rendered obsolete by the coercions.
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
a78302243c refactor: strengthen Syntax signatures
Most notable change: `Quote` is now parameterized by the target kind.
Which means that `Name` etc. could actually have different
implementations for quoting into `term` and `level`, if that need ever
arises.
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
f90e4ae30c feat: more TSyntax API & coercions 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
a12cde41e1 chore: work around macro limitations
It would be nice if `macro` was as expressive as syntax quotations, but
right now it's not.
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
c202a2c013 feat: more antiquotation kinds 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
7bc95d3a95 chore: update stage0 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
9db8bac040 chore: prepare for next stage 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
d50b1aab89 feat: <|> may produce a choice node of antiquotations 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
ab08bffbec chore: Nix: fix stage0-from-input 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
4b78d02a5e fix: do not discriminate anonymous antiquots after all 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
9b71fbb461 chore: default pp.rawOnError to true for stage 0 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
43ba121e98 feat: upgrade TSyntax to union of kinds 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
3a61cc247e chore: introduce doSeq antiquotation 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
330245816c fix: macro: inferred syntax kinds for literal parsers 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
2ef3636022 fix: elaborating category quotations 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
4588b1ec90 fix: ignore withPosition when binding macro arguments
Would be nice to generalize this at some point
2022-06-27 22:37:02 +02:00
Sebastian Ullrich
80a92cceeb fix: avoid choice nodes with LeadingIdentBehavior.both 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
e6954bb4f3 fix: quote Name.anonymous 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
7d48d125da fix: store syntax kinds of parser aliases in order to construct correct antiquotations in macro and elab 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
2c54a0d17a feat: allow anonymous antiquotations for tacticSeq 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
df499a5b64 feat: early coercion from TSyntax to Syntax 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
c2b4c37792 refactor: make Init.Coe independent of Init.Notation 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
3b3961a89b chore: disable some anonymous antiquotations 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
8bbae8b8da feat: introduce TSyntax 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
292d24ba19 feat: always store quoted kind in antiquotation kind 2022-06-27 22:37:02 +02:00
Sebastian Ullrich
0bd864deca fix: nesting of pattern info nodes 2022-06-27 22:37:02 +02:00
Leonardo de Moura
6ebae968a7 feat: use IO.getRandomBytes to initialize random seed
See https://github.com/leanprover/lean4-samples/pull/2
2022-06-27 13:01:20 -07:00
Leonardo de Moura
f4e083d507 feat: dot notation and aliases
This commit addresses the issue raised at
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Namespace-based.20overloading.20does.20not.20find.20exports/near/282946185
2022-06-27 12:42:25 -07:00
Leonardo de Moura
fc25689f21 feat: add Syntax.eraseSuffix? 2022-06-27 10:30:57 -07:00
Leonardo de Moura
3f0a9eb424 test: add test for issue #1253
closes #1253
2022-06-27 09:56:47 -07:00
Leonardo de Moura
c498285d94 chore: add missing double backtick 2022-06-27 09:56:47 -07:00
Sebastian Ullrich
3eeeca22e2 chore: lean-gdb: recursive values & tag 2022-06-26 18:47:47 +02:00
Sebastian Ullrich
5a0c3b8d80 fix: String.isNat 2022-06-25 18:42:08 +02:00
Wojciech Nawrocki
aacfd11508 feat: boolean inequality lemmas 2022-06-25 11:18:09 +02:00
E.W.Ayers
cc9293af09 doc: isDefEq explain mvar levels 2022-06-24 15:24:52 -07:00
Sebastian Ullrich
8979ed42a4 refactor: file worker: wait on header task before dispatching requests 2022-06-24 19:02:00 +02:00
Sebastian Ullrich
e14b4ab0e4 feat: file worker: make header snapshot asynchronous 2022-06-24 19:02:00 +02:00
Leonardo de Moura
220d2e3816 feat: add filterTR and [csimp] theorem 2022-06-24 06:40:38 -07:00
Leonardo de Moura
1fd2b17a92 fix: bug at addDependencies
closes #1247
2022-06-24 06:20:00 -07:00
Gabriel Ebner
ec4200fc75 chore: remove unnecessary ppLine 2022-06-24 10:59:55 +02:00
Gabriel Ebner
233a787e65 chore: add test for sepByIndent.formatter 2022-06-24 10:59:55 +02:00
Gabriel Ebner
d5142ddeb8 chore: add sepByIndent.formatter 2022-06-24 10:59:55 +02:00
Gabriel Ebner
733f220ee3 feat: $[...]* antiquotations for sepByIndent 2022-06-24 10:59:55 +02:00
Leonardo de Moura
09c4af26fc fix: ConstantInfo.all for consistency 2022-06-23 16:41:54 -07:00
Leonardo de Moura
88fae4e3d6 chore: update stage0 2022-06-23 16:41:05 -07:00
Leonardo de Moura
98c775da34 feat: save mutual block information for definitions/theorems/opaques 2022-06-23 16:39:51 -07:00
Leonardo de Moura
ea3e27bbc4 chore: update stage0 2022-06-23 16:13:49 -07:00
Leonardo de Moura
69a446c8d1 feat: add field all to DefinitionVal and TheoremVal
Remark: we need an update stage0, and the field is not being updated
correctly set yet.
2022-06-23 16:13:26 -07:00
Leonardo de Moura
da63e003e7 chore: update stage0 2022-06-23 13:32:13 -07:00
Leonardo de Moura
1e4e683e91 chore: update stage0 2022-06-23 13:30:04 -07:00
Henrik Böving
0fde2db75e feat: improve the heuristic for notation delab
Instead of the previous constraints on the right hand side that only
allowed a permutation of variables as parameters to a function the
new heuristic allows anything to the right of a function as long as
each variable only appears at most once.
2022-06-23 13:27:53 -07:00
Leonardo de Moura
3a89723f8c chore: update stage0 2022-06-23 10:23:37 -07:00
Leonardo de Moura
96a72d67f2 fix: avoid unnecessary dependencies at mkMatcher
fixes #1237
2022-06-23 10:21:32 -07:00
Leonardo de Moura
17fa60e1ec chore: remove dead code 2022-06-23 09:31:52 -07:00
Sebastian Ullrich
17c2e6d529 feat: publish fatal progress after worker crash 2022-06-23 09:24:27 -07:00
Connor Baker
c213e0e880 doc: fix overwide view when using Alectryon 2022-06-23 18:23:28 +02:00
Leonardo de Moura
939f8d9f16 fix: fixes #1240 2022-06-23 05:53:06 -07:00
Sebastian Ullrich
1f13729756 feat: show term goal at end of term as well 2022-06-23 14:44:19 +02:00
Sebastian Ullrich
13bcbce144 chore: fix Nix test output filter 2022-06-23 14:05:53 +02:00
Sebastian Ullrich
1712d0fee3 chore: update LeanInk
Resolves leanprover/LeanInk#20
2022-06-23 11:32:16 +02:00
Leonardo de Moura
108bc4c27f fix: extCore 2022-06-22 19:40:06 -07:00
Leonardo de Moura
a84b9b2e7b doc: update release notes 2022-06-22 19:34:29 -07:00
Leonardo de Moura
53acd3e355 feat: allow ext conv tactic to go inside let-declarations 2022-06-22 19:27:04 -07:00
Leonardo de Moura
4d1c6dd557 feat: add zeta conv tactic 2022-06-22 19:15:10 -07:00
Leonardo de Moura
a802544c90 fix: intro tactic at let-expr 2022-06-22 16:10:33 -07:00
Leonardo de Moura
2a940dd4ae feat: add Expr.collectFVars, LocalDecl.collectFVars, Pattern.collectFVars, and AltLHS.collectFVars
They are all in `MetaM`.

These are helper functions for issue #1237. We need to "cleanup" the
local context before trying to compile the match-expression.

see issue #1237
2022-06-22 15:53:43 -07:00
Leonardo de Moura
9678be4d81 fix: store discharge depth when caching simp results
Closes #1234
2022-06-21 15:35:47 -07:00
Leonardo de Moura
65d24f4e39 fix: typo at LinearExpr.toExpr
closes #1236
2022-06-21 14:28:26 -07:00
Sebastian Ullrich
71b99423e8 chore: Nix: fix CI 2022-06-21 23:11:57 +02:00
Sebastian Ullrich
02e5865a02 chore: Nix: stop pinning Nix in ciShell 2022-06-21 22:57:39 +02:00
Sebastian Ullrich
ce73728be3 chore: Nix: avoid build closure dependencies on stdenv 2022-06-21 21:11:59 +02:00
Sebastian Ullrich
dd58b5c2df chore: Nix: cache correct output 2022-06-21 21:10:08 +02:00
Sebastian Ullrich
e20f2e076e chore: Nix: cache lean-bin-tools 2022-06-21 20:52:39 +02:00
Leonardo de Moura
e442fbbf54 fix: remove kabstractWithPred
The function `kabstractWithPred` was never used, and introduced the
bug exposed by issue #1235.

fixes #1235
2022-06-20 16:35:18 -07:00
Leonardo de Moura
986de33097 fix: fixes #1230 2022-06-20 09:58:27 -07:00
E.W.Ayers
b6f251bcd3 fix: SubExpr.Pos.toString not terminating
fixes 1232
2022-06-19 16:04:50 -07:00
Sebastian Ullrich
58d5a11928 Revert "fix: induction: do not register _ as binder in info tree"
This reverts commit 143b2b49c8.
2022-06-18 17:24:08 +02:00
Sebastian Ullrich
99607c208c Revert "fix: intro/intros: do not register _ as binder in info tree"
This reverts commit 41dfd06e8c.
2022-06-18 17:24:08 +02:00
Sebastian Ullrich
a4236c0721 fix: ignore hygiened names in unused variables linter 2022-06-18 17:24:08 +02:00
Sebastian Ullrich
8aea00213c chore: clean up doc/flake.nix 2022-06-18 13:21:02 +02:00
Wojciech Nawrocki
7624e25de0 fix: don't duplicate tags in formatter 2022-06-18 10:07:53 +02:00
Wojciech Nawrocki
b1ef58d3cc fix: tag idents so that ofFieldInfo nodes are preserved 2022-06-18 10:07:53 +02:00
E.W.Ayers
ee6ba180ea fix: remove fix2 2022-06-17 17:47:51 -07:00
E.W.Ayers
18ba16ded9 feat: string representation of Pos
This is needed because JSON will otherwise lossily
convert big nats to floats.
2022-06-17 17:47:51 -07:00
E.W.Ayers
933964f2a4 chore: rm SubExpr.mapPos because it is not useful 2022-06-17 17:47:51 -07:00
E.W.Ayers
114bbc78ed test: numBinders 2022-06-17 17:47:51 -07:00
E.W.Ayers
8b1130c6dd test: replaceSubexpr pure p e = e
This found a bug in lensCoord which I fixed.
2022-06-17 17:47:51 -07:00
E.W.Ayers
b110d800e9 fix: add ExprTraversal to Meta 2022-06-17 17:47:51 -07:00
E.W.Ayers
4a70143aaf style: minor formatting changes 2022-06-17 17:47:51 -07:00
E.W.Ayers
3c14c97195 test: add unit test for Expr lens 2022-06-17 17:47:51 -07:00
E.W.Ayers
a7c33a963f doc: docstrings for List.isPrefixOf 2022-06-17 17:47:51 -07:00
E.W.Ayers
0707e4d442 fix: traverseChildrenWithPos bug 2022-06-17 17:47:51 -07:00
E.W.Ayers
0e84f67d99 feat: with pos expr traversal functions 2022-06-17 17:47:51 -07:00
E.W.Ayers
562070fe8b refactor: more extract methods from transform 2022-06-17 17:47:51 -07:00
E.W.Ayers
c8fc371eb9 fix: test 2022-06-17 17:47:51 -07:00
E.W.Ayers
8311c88fd0 refactor: extract methods from Lean.Meta.transform
Lean.Meta.transform is created with a series of recursive
visit functions. However these visit functions are useful
on their own outside of transform for traversing expressions.

This commit moves the visit functions outside the main function.
2022-06-17 17:47:51 -07:00
E.W.Ayers
ece1c1085c feat: add Expr lensing functions using SubExpr.Pos 2022-06-17 17:47:51 -07:00
E.W.Ayers
2fe933cdf5 refactor: make SubExpr.Pos a definition
Instead of an abbreviation. It is easier to understand
Pos operations in terms of 'push' and 'pop' rather than
through arithmetic.
2022-06-17 17:47:51 -07:00
Leonardo de Moura
bbc196eeb7 fix: make sure WF/Fix.lean tolerates MatcherApp.addArg? failures
see #1228
2022-06-17 17:37:33 -07:00
Leonardo de Moura
52a0de00e4 feat: report error on ambiguous export and open commands
This commit improves the fix for issue #1224
2022-06-17 09:58:36 -07:00
Leonardo de Moura
e985eb2b8a fix: refine resolveNamespace
see issue #1224
2022-06-17 09:51:00 -07:00
Leonardo de Moura
f0e2696ec8 doc: update release notes 2022-06-16 18:22:23 -07:00
Leonardo de Moura
81a685d97c test: issue #1224
closes #1224
2022-06-16 18:01:09 -07:00
Leonardo de Moura
a6462f5bd8 feat: improve open/export 2022-06-16 18:00:33 -07:00
Leonardo de Moura
d5476fb3b3 refactor: move toMessageList, add throwErrorWithNestedErrors 2022-06-16 18:00:09 -07:00
Leonardo de Moura
8ca3e14651 feat: change namespace resolution procedure
see #1224
2022-06-16 17:31:49 -07:00
Leonardo de Moura
d56163bd0e refactor: resolveNamespace now return a List 2022-06-16 17:16:36 -07:00
François G. Dorais
bc206b2992 fix: LawfulBEq class
make arguments implicit and protect `LawfulBEq.rfl`
2022-06-16 15:33:32 -07:00
Leonardo de Moura
8d9428261e chore: remove Fix.lean
see #1208
2022-06-16 15:30:47 -07:00
Leonardo de Moura
9e7a6fa085 chore: remove dead structure 2022-06-16 15:23:23 -07:00
Sebastian Ullrich
b1e3607739 fix: match tactic with multiple LHSs 2022-06-16 15:21:46 -07:00
Sebastian Ullrich
0777d01cf9 chore: update Lake 2022-06-16 23:33:57 +02:00
Sebastian Ullrich
72a5c582cf chore: Nix: ignore build messages in test capture 2022-06-16 23:33:57 +02:00
Sebastian Ullrich
4212cc740b refactor: move linebreak check into sepBy(1)Indent
Co-authored-by: Gabriel Ebner <gebner@gebner.org>
2022-06-16 23:33:57 +02:00
Sebastian Ullrich
6f096e0f0d chore: fix tests 2022-06-16 23:33:57 +02:00
Sebastian Ullrich
6982536108 fix: one more struct instance syntax manipulation 2022-06-16 23:33:57 +02:00
Sebastian Ullrich
0f6e6c8a51 chore: update stage0 2022-06-16 23:33:57 +02:00
Sebastian Ullrich
b585b2251e fix: adapt to stricter grammar 2022-06-16 23:33:57 +02:00
Sebastian Ullrich
ce054fb2e7 fix: introduce semicolonOrLinebreak, replace many(1) with sepBy(1) where appropriate 2022-06-16 23:33:57 +02:00
Sebastian Ullrich
7a3ee51d05 doc: missing word 2022-06-16 10:12:07 +02:00
Mariana Alanis
198179d0cc fix: add a better handling in case only worker crashes (apply CR comments) 2022-06-15 18:40:44 -07:00
Mariana Alanis
e61799a77f fix: add a better handling in case only worker crashes (CR comments) 2022-06-15 18:40:44 -07:00
Mariana Alanis
30f3d6f82d fix: add a better handling in case only worker crashes (CR comments) 2022-06-15 18:40:44 -07:00
Mariana Alanis
4d7d82af86 fix: add a better handling in case only worker crashes (CR comments) 2022-06-15 18:40:44 -07:00
Mariana Alanis
b0f9754e0f fix: add a better handling in case only worker crashes 2022-06-15 18:40:44 -07:00
Mariana Alanis
6b75ca9734 fix: add a better handlng in case only worker crashes (and server stays available) 2022-06-15 18:40:44 -07:00
Leonardo de Moura
d2888a49d7 chore: remove old hack that is not needed anymore 2022-06-15 16:36:54 -07:00
Leonardo de Moura
3228db29dd chore: use double ticks 2022-06-15 07:17:17 -07:00
Sebastian Ullrich
524ae5abf7 chore: CI: purge ccache 2022-06-15 13:39:24 +02:00
Sebastian Ullrich
23d157a3ff chore: remove dead code 2022-06-15 12:43:59 +02:00
Sebastian Ullrich
bfce841985 chore: update stage0 2022-06-15 10:01:47 +02:00
Leonardo de Moura
5896e6f1d6 chore: fix docs 2022-06-14 17:35:33 -07:00
Leonardo de Moura
540e9e85f3 chore: update release notes 2022-06-14 17:31:26 -07:00
Leonardo de Moura
989d8f04e1 chore: fix tests 2022-06-14 17:27:13 -07:00
Leonardo de Moura
f6d1e48cb8 fix: constant => opaque issues 2022-06-14 17:19:54 -07:00
Leonardo de Moura
fb55ec29e1 chore: update stage0 2022-06-14 17:14:44 -07:00
Leonardo de Moura
22c8f10b12 chore: remove constant command 2022-06-14 17:14:28 -07:00
Leonardo de Moura
02c4e548df feat: replace constant with opaque 2022-06-14 17:02:59 -07:00
Leonardo de Moura
ac33193b30 chore: update stage0 2022-06-14 16:45:20 -07:00
Leonardo de Moura
3b259afaf0 chore: fix tests 2022-06-14 16:43:22 -07:00
Leonardo de Moura
346c4beb70 feat: elaborate opaque command 2022-06-14 16:36:24 -07:00
Leonardo de Moura
794021b9e4 chore: adjust codebase
`opaque` is now a command keyword
2022-06-14 16:32:53 -07:00
Leonardo de Moura
5193c6d0ef chore: update stage0 2022-06-14 16:23:49 -07:00
Leonardo de Moura
05778565ab feat: add opaque command
It will replace the `constant` command. See
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/What.20is.20.60opaque.60.3F/near/284926171
2022-06-14 16:22:36 -07:00
Jakob von Raumer
d7cb93e9e4 feat: allow conv mode's arg command to access implicit arguments 2022-06-14 16:15:38 -07:00
Leonardo de Moura
d78e7cd011 feat: macro expand cases and induction tactics multiple LHSs 2022-06-14 14:18:52 -07:00
Leonardo de Moura
3a1dc5e066 fix: support new inductionAlt syntax at Linter/Basic.lean 2022-06-14 11:31:49 -07:00
Leonardo de Moura
bd2cccf287 chore: use double tick 2022-06-14 11:30:55 -07:00
Leonardo de Moura
2dad133208 chore: update stage0 2022-06-14 11:26:06 -07:00
Leonardo de Moura
daeb271678 feat: update induction and cases syntax
We can now write
```
induction x with
| foo | bar => ...
| boo => ...
```

TODO: expand alternatives containing multiple LHSs.
2022-06-14 11:25:15 -07:00
Leonardo de Moura
05a72a9e00 chore: update stage0 2022-06-14 11:17:33 -07:00
Leonardo de Moura
7c9b5b7147 feat: prepare to support multi-cases at cases and induction
We want to be able to write
```
induction x with
| foo | bar => ...
| boo => ...
```
2022-06-14 11:16:58 -07:00
Sebastian Ullrich
43b08239b0 fix: further conv goal state refinements 2022-06-14 11:09:47 +02:00
Sebastian Ullrich
7bb94abb62 feat: trace.Elab.input
Unlike Elab.command, it does not contain macro expansions
2022-06-14 10:41:56 +02:00
Leonardo de Moura
77ae79be46 chore: use let/if in do blocks 2022-06-13 17:10:14 -07:00
Leonardo de Moura
7dbdfa090a chore: remove debugging leftovers 2022-06-13 16:37:31 -07:00
E.W.Ayers
13e286f545 doc: fix docstring for InteractiveGoal 2022-06-13 16:32:01 -07:00
E.W.Ayers
2edf02544e chore: rm ExprWithCtx
We will make this a separate PR
2022-06-13 16:32:01 -07:00
E.W.Ayers
367bde3601 chore: revert "refactor: replace InfoWithCtx with ExprWithCtx"
This reverts commit db342793d5.
2022-06-13 16:32:01 -07:00
E.W.Ayers
f64cb95eca refactor: replace InfoWithCtx with ExprWithCtx
This is potentially controversial. There are still some [todo]s that need sorting.
2022-06-13 16:32:01 -07:00
E.W.Ayers
3d561a3ab0 doc: add docstrings for interactive 2022-06-13 16:32:01 -07:00
E.W.Ayers
e3d2080232 refactor: PPExprTaggedRequest -> PPExprTaggedParams 2022-06-13 16:32:01 -07:00
E.W.Ayers
fd66e70d1e fix: explicit structure for PPExprTaggedRequest 2022-06-13 16:32:01 -07:00
E.W.Ayers
69facfbe8e fix: remove Optional from InteractiveHypothesisBundle.fvarIds 2022-06-13 16:32:01 -07:00
E.W.Ayers
45e3c72be7 refactor: InteractiveHypothesis → InteractiveHypothesisBundle 2022-06-13 16:32:01 -07:00
Ed Ayers
5130da82a8 doc: src/Lean/Widget/InteractiveGoal.lean
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2022-06-13 16:32:01 -07:00
E.W.Ayers
cea53fc53e fix: tests
Caused by a classic imperative programming bug oops
2022-06-13 16:32:01 -07:00
E.W.Ayers
f2a874ebaa fix: handle inaccessible fvar names correctly 2022-06-13 16:32:01 -07:00
E.W.Ayers
675147dcfc fix: make InteractiveHyp.fvarIds optional
This is for backwards compat.
2022-06-13 16:32:01 -07:00
E.W.Ayers
0f61d1dc59 refactor: key fields are now f/mvarid fields 2022-06-13 16:32:01 -07:00
E.W.Ayers
4165b7e8ba doc: ToHide.collect 2022-06-13 16:32:01 -07:00
E.W.Ayers
6e1c9653d9 feat: Add a key field to InteractiveGoal
This is used to uniquely identify InteractiveGoals and
InteractiveHypotheses. This makes it easier to do
contextual suggestions: eg the infoview can send a message
saying "the user clicked on subexpression 5 in hypothesis N in goal G"
where N and G are unique identifiers for a goal rather than pretty names
which may be non-unique or indices which may be difficult to compute
(eg in infoview there is a mode where hypotheses are reversed or filtered).

While adding these I also refactored the InteractiveGoal generating function.
I unwrapped a fold in to a for/in loop with mutating variables which is a
little easier to read.
2022-06-13 16:32:01 -07:00
Wojciech Nawrocki
351be06a21 feat: ppExprTagged RPC call 2022-06-13 16:32:01 -07:00
Wojciech Nawrocki
4972f214be fix: sorried errors in rpcServerMethod 2022-06-13 16:32:01 -07:00
Leonardo de Moura
c2fdcad443 chore: update stage0 2022-06-13 16:23:53 -07:00
Leonardo de Moura
e52a7bdf42 feat: let/if indentation in do blocks
closes #1120
2022-06-13 16:18:49 -07:00
Leonardo de Moura
415f5f2a42 chore: style 2022-06-13 15:59:55 -07:00
Leonardo de Moura
dee712ec7e chore: fix test
Pushed the wrong file in previous commit.

see #490
2022-06-13 14:06:56 -07:00
Leonardo de Moura
9ba5831de8 fix: _root_ prefix in declarations
closes #490
2022-06-13 14:03:18 -07:00
Leonardo de Moura
328586988c chore: style 2022-06-13 13:58:29 -07:00
Sebastian Ullrich
bda871da25 feat: RBTree.union/diff 2022-06-13 11:12:51 +02:00
Leonardo de Moura
fb574af873 fix: mkSplitterProof
This commit fixes the first issue reported at #1179

closes #1179
2022-06-12 19:38:54 -07:00
Wojciech Nawrocki
46257dfb0e feat: show bitwise terminates 2022-06-12 14:01:05 -07:00
Wojciech Nawrocki
4d05803782 feat: WF lemma for Nat division 2022-06-12 14:01:05 -07:00
Wojciech Nawrocki
2a53857928 feat: add strong Nat induction principle 2022-06-12 14:01:05 -07:00
Wojciech Nawrocki
ff15e31e85 refactor: remove redundant theorem 2022-06-12 14:01:05 -07:00
Leonardo de Moura
09d1530d8e feat: detect unexpected occurrences of match-expression minor premises
The error message is far from perfect, but it is better than ignoring
the issue and failing later with an even more incomprehensible error
message.

see #1179
2022-06-12 12:07:42 -07:00
Leonardo de Moura
8a8a8b5e48 chore: style 2022-06-10 18:27:43 -07:00
Jakob von Raumer
033618ad5e fix: indices in conv arg now count arguments with forward dependencies 2022-06-10 18:25:34 -07:00
Leonardo de Moura
17db981880 fix: equation theorem for match with more than one "as" pattern
see #1195
see #1179
2022-06-10 18:23:13 -07:00
tydeu
78c57161d8 chore: update Lake 2022-06-10 17:50:05 -07:00
Leonardo de Moura
4ba7174c0c fix: universe level parameter stabilitity issue
See comment.
2022-06-10 14:08:08 -07:00
Sebastian Ullrich
67087ac16e fix: bad reassignment 2022-06-10 18:28:31 +02:00
Sebastian Ullrich
efff36d3e9 chore: update stage0 2022-06-10 18:17:57 +02:00
Sebastian Ullrich
61232e788a fix: check types at do pattern reassignment 2022-06-10 17:31:36 +02:00
Sebastian Ullrich
a44fec2262 chore: CI: exclude test harder 2022-06-10 12:02:23 +02:00
Sebastian Ullrich
8c377436f4 fix: do not report unused variables in unfinished declarations 2022-06-10 11:27:11 +02:00
Sebastian Ullrich
45636324f9 chore: CI: exclude nonreproducible test 2022-06-10 11:12:09 +02:00
Leonardo de Moura
97e689d670 chore: add link from Lean 4 manual to FP in Lean 2022-06-09 16:28:54 -07:00
Leonardo de Moura
0ac863b353 chore: add link to the new book 2022-06-09 16:09:07 -07:00
Sebastian Ullrich
41dfd06e8c fix: intro/intros: do not register _ as binder in info tree
Fixes #1204
2022-06-09 15:23:56 +02:00
Chris Lovett
33159b51e5 chore: build integration with TPIL 2022-06-09 09:23:04 +02:00
Leonardo de Moura
d0499ebf4d fix: fixes #1200 2022-06-08 10:18:05 -07:00
Leonardo de Moura
fa64c072ab feat: where declarations at instances
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Local.20functions.20in.20instances/near/285333999
2022-06-07 18:48:15 -07:00
Leonardo de Moura
0c28d4ff4d chore: update stage0 2022-06-07 18:42:16 -07:00
Leonardo de Moura
1e59eb2290 chore: update whereStructInst 2022-06-07 18:41:43 -07:00
Leonardo de Moura
ce78c17f2d chore: update stage0 2022-06-07 17:54:42 -07:00
Leonardo de Moura
041827bed5 chore: unused variables 2022-06-07 17:54:10 -07:00
Leonardo de Moura
a18c78e617 chore: update stage0 2022-06-07 16:48:55 -07:00
Leonardo de Moura
c2ddebc193 chore: unused variables 2022-06-07 16:47:04 -07:00
Sebastian Ullrich
130cc8bbd5 chore: fix test 2022-06-07 16:37:45 -07:00
Sebastian Ullrich
f9e2a65f75 chore: further cleanup
Co-authored-by: Gabriel Ebner <gebner@gebner.org>
2022-06-07 16:37:45 -07:00
Sebastian Ullrich
8eefbf5227 chore: further clean up refactored code 2022-06-07 16:37:45 -07:00
Sebastian Ullrich
897a5de6ac chore: revert some questionable signature changes 2022-06-07 16:37:45 -07:00
Sebastian Ullrich
fb2a2b3de2 fix: fixup previous commit 2022-06-07 16:37:45 -07:00
Sebastian Ullrich
ae7b895f7a refactor: unname some unused variables 2022-06-07 16:37:45 -07:00
Sebastian Ullrich
8ffa07ab25 fix: goal state on conv => 2022-06-07 17:43:16 +02:00
Sebastian Ullrich
a07e9df66e fix: use goal prefix in plain goal response 2022-06-07 17:42:09 +02:00
Sebastian Ullrich
388ed62858 chore: update Alectryon 2022-06-07 17:14:41 +02:00
Chris Lovett
885deec745 doc: add link to short quickstart video 2022-06-06 18:32:11 -07:00
Leonardo de Moura
09ddf76029 feat: simp_all now uses dependent hypotheses for simplification
However, it does not simplify them.

closes #1194
2022-06-06 18:31:34 -07:00
Leonardo de Moura
875e71a0d7 chore: unused variables at Simp.lean 2022-06-06 18:24:10 -07:00
Leonardo de Moura
71226243fd fix: fixes #1192 2022-06-06 18:20:45 -07:00
Leonardo de Moura
0f111da64c chore: unused variables at Inductive.lean 2022-06-06 18:15:25 -07:00
Leonardo de Moura
5055855637 feat: improve default simp discharge method
closes #1193
2022-06-06 17:29:12 -07:00
Leonardo de Moura
3d04899e42 refactor: add unifyEq? 2022-06-06 15:53:40 -07:00
Leonardo de Moura
c9c9b8d835 chore: avoid code duplication 2022-06-06 15:53:40 -07:00
Leonardo de Moura
7dab01be1b chore: unused eqns 2022-06-06 15:53:40 -07:00
Leonardo de Moura
2832442e7a fix: unfold declarations tagged with [matchPattern] at reduceMatcher? even if transparency setting is not the default one
see #1193

It fixes one of the issues exposed at the issue above.
2022-06-06 15:53:40 -07:00
Leonardo de Moura
e24483d6d3 doc: expand isGenDiseq comment 2022-06-06 15:53:40 -07:00
larsk21
60c8a72262 fix: unused variables linter: consider induction variables as pattern variables 2022-06-06 15:53:10 -07:00
larsk21
a9293410a2 fix: unused variables linter: ignore structure, class and inductive signatures 2022-06-06 15:53:10 -07:00
Wojciech Nawrocki
5b13a4909b doc: fix transform docstring 2022-06-06 23:06:47 +02:00
Sebastian Ullrich
143b2b49c8 fix: induction: do not register _ as binder in info tree 2022-06-06 23:05:12 +02:00
E.W.Ayers
d55daf80d4 doc: fix misleading SubExpr docstring 2022-06-06 09:37:51 -07:00
Leonardo de Moura
d00d8a2104 fix: typo at copyDefaultValue?
see #1190
2022-06-06 07:57:23 -07:00
Leonardo de Moura
22281f25c8 fix: typo at sameHeadSymbol
see #1190
2022-06-06 07:46:57 -07:00
Sebastian Ullrich
7428dc5e71 Revert "chore: CI: use publish-unit-test-result-action"
Was just an experiment, its benefit is negligible

This reverts commit 3575981ee6.
2022-06-05 14:23:20 +02:00
Sebastian Ullrich
3c41962275 refactor: Expr.forEach' use in unused variables linter 2022-06-05 14:16:40 +02:00
Sebastian Ullrich
85e0e0ad20 doc: fix Expr.forEach' docstring 2022-06-05 14:16:29 +02:00
Sebastian Ullrich
3575981ee6 chore: CI: use publish-unit-test-result-action 2022-06-05 14:10:17 +02:00
Sebastian Ullrich
7870c24cdd chore: update stage0 2022-06-04 13:57:39 +02:00
Sebastian Ullrich
ec045bfbb8 feat: $_ antiquotation pattern 2022-06-04 13:57:04 +02:00
Sebastian Ullrich
a65197bb78 doc: update changelog 2022-06-03 22:58:38 +02:00
Sebastian Ullrich
05c5dd4441 fix: unused variables linter: search fvar aliases in tactics 2022-06-03 22:37:38 +02:00
Sebastian Ullrich
f3a7654a63 fix: unused variables linter: find nested uses in tactics 2022-06-03 22:37:38 +02:00
E.W.Ayers
1785ab142e refactor: move Lean.PrettyPrinter.Delaborator.SubExpr to Lean.SubExpr
This is because SubExpr has uses outside the Delaborator.

Closes #1183
2022-06-03 12:38:14 -07:00
Sebastian Ullrich
a0624ec296 chore: CI: ignore foreigntest on Linux release 2022-06-03 17:04:06 +02:00
Leonardo de Moura
9d6b67eae2 fix: remove check from Simp.synthesizeArgs
Some `simp` dischargers can handle metavariables (e.g,
`assumption`). See new test.

closes #1184
2022-06-03 07:40:30 -07:00
Sebastian Ullrich
3cfbdd134a fix: update Alectryon 2022-06-03 16:05:59 +02:00
Sebastian Ullrich
0b264889ae fix: goal state on ; after · 2022-06-03 13:41:04 +02:00
Sebastian Ullrich
d15934c0ac chore: Nix: Bring-Your-Own-Emacs .#emacs-path-dev 2022-06-03 13:41:04 +02:00
Sebastian Ullrich
cfa14b3ce0 chore: nix flake update 2022-06-03 13:41:04 +02:00
larsk21
caa8804a1d feat: add nolint options for function arguments and pattern variables 2022-06-03 13:03:52 +02:00
larsk21
93480a3e05 fix: consider tactic mvar assignments for used variables 2022-06-03 13:03:52 +02:00
larsk21
bf907d7b8c fix: ignore exposed function arguments in unused variables linter 2022-06-03 13:03:52 +02:00
larsk21
57c8c76cd0 fix: use findModuleRefs in unused variables linter 2022-06-03 13:03:52 +02:00
larsk21
b556e73657 refactor: extend Lsp.ModuleRefs in Server.References 2022-06-03 13:03:52 +02:00
larsk21
cf4e106304 fix: unused variables linter review comments
- ignore unused variables in dep arrows
- avoid negated options
- make syntax stack generation more performant
- make ignore functions more extensible
- change message severity to `warning`
2022-06-03 13:03:52 +02:00
larsk21
b708eaec2c fix: forward lean options to workers 2022-06-03 13:03:52 +02:00
larsk21
393fdef972 fix: disable linters in tests 2022-06-03 13:03:52 +02:00
larsk21
37d5f8e74a feat: add unused variables linter 2022-06-03 13:03:52 +02:00
larsk21
8824a479a5 fix: add additional information to Lean.Server.Reference 2022-06-03 13:03:52 +02:00
larsk21
1a1f8f52a5 fix: run linters after elaboration 2022-06-03 13:03:52 +02:00
Leonardo de Moura
8649483b41 feat: produces an error if the declaration body contains a universe parameter that does not occur in the declaration type nor is explicitly provided
closes #898
2022-06-02 19:43:09 -07:00
Leonardo de Moura
484e510221 feat: do not use pp.inaccessibleNames = true at getInteractiveTermGoal
See discussion at https://github.com/leanprover/vscode-lean4/issues/76

We also use `pp.inaccessibleNames = false` in error messages. In this
setting, an inaccessible name is displayed in the context only if the
target type depends on it.
2022-06-02 16:22:43 -07:00
Leonardo de Moura
878ef3a281 feat: improve acyclic tactic
closes #1182
2022-06-02 15:25:14 -07:00
Sebastian Ullrich
1fff412b1f fix: regressions from previous commit 2022-06-02 19:04:47 +02:00
Sebastian Ullrich
ddfbf6bf9b fix: show namespace when hovering over declaration name 2022-06-02 18:17:21 +02:00
Leonardo de Moura
32db316166 fix: enumeration type noConfusion was not registered
This commit fixes issue reported at
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/.28kernel.29.20function.20expected.20.2EnoConfusion/near/284634050
2022-06-01 17:58:46 -07:00
Gabriel Ebner
9a273b85a3 fix: no sorry-warning for missing match cases 2022-06-01 07:41:52 -07:00
Leonardo de Moura
bf0b675ca6 chore: fix tests 2022-06-01 06:36:25 -07:00
Leonardo de Moura
9102f8cb13 fix: generate sorry warning only if there are no error messages
see #1163
2022-06-01 06:32:05 -07:00
Leonardo de Moura
9290a0e9b1 chore: fix tests 2022-05-31 18:17:56 -07:00
Leonardo de Moura
ac440e757d chore: update stage0 2022-05-31 18:14:05 -07:00
Leonardo de Moura
5302267220 test: for #1163 2022-05-31 18:09:27 -07:00
Leonardo de Moura
2e6dae01f0 chore: synthetic := false by default at sorryAx 2022-05-31 18:08:10 -07:00
Leonardo de Moura
2b2f315fb9 chore: fix tests 2022-05-31 18:01:48 -07:00
Leonardo de Moura
64c36fffda feat: generate warning message if declaration has a non-synthetic sorry
closes #1163
2022-05-31 18:00:48 -07:00
Leonardo de Moura
0631c90794 feat: implement MonadLog at CoreM 2022-05-31 17:40:55 -07:00
Leonardo de Moura
caa79ca04f refactor: move MonadLog 2022-05-31 16:50:48 -07:00
Leonardo de Moura
be69d04af4 feat: add Declaration.hasSorry 2022-05-31 16:39:37 -07:00
Leonardo de Moura
5f7cc78f17 fix: remove unnecessary let-expressions when computing the motive
fixes #1155
2022-05-31 07:14:56 -07:00
Leonardo de Moura
704242f865 feat: zetaReduce should expand nested let-expressions too 2022-05-31 07:01:52 -07:00
Leonardo de Moura
d8aab852e8 feat: add usedLetOnly parameter to Meta.transform 2022-05-31 07:00:53 -07:00
Leonardo de Moura
e997cd94c6 chore: style 2022-05-31 06:04:48 -07:00
larsk21
a741540400 fix: relax InfoTree.visitM when visiting holes 2022-05-31 13:14:24 +02:00
Wojciech Nawrocki
115c564b18 feat: go to head constant in applications
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2022-05-31 00:07:56 +02:00
Wojciech Nawrocki
737e872ee0 feat: set tagAppFns in explicit exprToInteractive 2022-05-31 00:07:56 +02:00
Wojciech Nawrocki
9c9407e722 feat: propagate tagAppFns in delaborator 2022-05-31 00:07:56 +02:00
Wojciech Nawrocki
cd47c30e47 chore: review fixes 2022-05-31 00:07:56 +02:00
Wojciech Nawrocki
8c67afae2f feat: generalize getGoToLocation RPC 2022-05-31 00:07:56 +02:00
Wojciech Nawrocki
8c5cebfb11 chore: default optional LSP fields 2022-05-31 00:07:56 +02:00
Wojciech Nawrocki
aef8d32d0b feat: add RPC call to retrieve defn/decl/type defn 2022-05-31 00:07:56 +02:00
Wojciech Nawrocki
9c058a5798 chore: remove some unnecessary partial 2022-05-31 00:07:56 +02:00
Wojciech Nawrocki
e555490ee2 feat: store subexpression positions 2022-05-31 00:07:56 +02:00
Wojciech Nawrocki
25a8646a5f feat: add showDocument client capability 2022-05-31 00:07:56 +02:00
ammkrn
102e957bb5 feat: support proofs in deriving DecidableEq
The derive handler for `DecidableEq` does not currently support proofs
in constructor arguments/structure fields. For example, deriving
`DecidableEq` for `Fin n` will fail, because of the field `isLt`. This
change checks whether the elements being tested are proofs, and if so,
changes the equality proof to just `rfl`.
2022-05-30 07:36:30 -07:00
Leonardo de Moura
9818de078b fix: fixes #1168 2022-05-30 07:24:23 -07:00
Leonardo de Moura
fb45eb4964 fix: universe polymorphic enumeration types
Fixes issue reported at https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Incorrect.20number.20of.20universe.20levels.20parameters/near/284283021
2022-05-30 06:43:46 -07:00
Leonardo de Moura
b0efae4823 chore: style 2022-05-30 06:43:46 -07:00
Sebastian Ullrich
ef9976ccda fix: do not discard macro exceptions in expandMacro? 2022-05-30 13:28:42 +02:00
Sebastian Ullrich
d3cf60e86a chore: further refine goal state heuristics 2022-05-30 13:27:56 +02:00
Sebastian Ullrich
b31690b1d7 fix: go to definition/goal state at end of syntax 2022-05-30 11:16:25 +02:00
Leonardo de Moura
ca6f53b407 feat: use subst_vars at builtin decreasing_tactic 2022-05-28 16:24:32 -07:00
Leonardo de Moura
6dc728cc60 chore: update stage0 2022-05-28 16:20:23 -07:00
Leonardo de Moura
40fc64480a feat: add tactic subst_vars 2022-05-28 16:19:34 -07:00
Leonardo de Moura
2c5bafcbd8 fix: dead variables at match equation hypotheses
This commit addresses an issue reported at https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Structural.20Recursion.20Problem/near/284238723
2022-05-28 16:09:35 -07:00
Leonardo de Moura
e26f86dd45 fix: improve simpH?, remove unnecessary hypotheses 2022-05-28 15:30:01 -07:00
Leonardo de Moura
34bbe5d12c feat: add simp theorem List.of_toArray_eq_toArray (as bs : List α) : (as.toArray = bs.toArray) = (as = bs) := by 2022-05-27 18:26:48 -07:00
Leonardo de Moura
fbd8224b4d fix: allow recursive occurrences in binder types at WF/PackDomain.lean
fixes #1171
2022-05-27 11:23:51 -07:00
Leonardo de Moura
3be437cad3 fix: make sure register_simp_attr declares an simp-like attribute parser for user simp attributes
closes #1164
2022-05-26 19:49:33 -07:00
Leonardo de Moura
7d8f8c0fbe chore: style 2022-05-26 15:18:07 -07:00
Leonardo de Moura
25126cd057 fix: autoParam is structure fields lost in multiple inheritance
closes #1158
2022-05-26 14:35:47 -07:00
Leonardo de Moura
b4c1163f8f chore: update stage0 2022-05-26 14:22:38 -07:00
Leonardo de Moura
f48b822532 feat: add field for storing autoParam information at StructureFieldInfo
We need this information when copying fields from parent structures.
We don't use hacks such as traversing the parent constructor type.
2022-05-26 14:21:03 -07:00
Leonardo de Moura
dcb974a1cf chore: remove unused parameter 2022-05-26 14:20:51 -07:00
Leonardo de Moura
fc606f3ab5 fix: closes #1156 2022-05-26 12:51:28 -07:00
Leonardo de Moura
988697b431 fix: fixes #1169 2022-05-26 07:05:32 -07:00
Leonardo de Moura
1d14637680 fix: missing withMVarContext 2022-05-26 06:18:14 -07:00
Leonardo de Moura
fad21a4cda chore: remove leftovers 2022-05-25 20:38:20 -07:00
Leonardo de Moura
944063682e fix: another specialize.cpp bug
This is just a workaround. This code has to be ported to Lean.

The issue has been reported at https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/.28kernel.29.20unknown.20constant/near/283750650
2022-05-25 20:36:18 -07:00
Leonardo de Moura
dca8a8ed98 fix: match or-pattern
This issue has been reported at
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Probably.20a.20bug/near/283779934
2022-05-25 20:05:46 -07:00
Leonardo de Moura
bef1cd4872 fix: make structure instance notation (e.g., { a, b }) works in patterns after we define the Set notation in Mathlib 2022-05-25 19:14:22 -07:00
Leonardo de Moura
a26827f58b chore: remove Context.main 2022-05-25 11:58:33 -07:00
Jannis Limperg
6dc5ddac35 fix: apply after-compilation attributes to inductive/structure decls
Attributes with `AttributeApplicationTime.afterCompilation` were
silently not applied to `inductive` and `structure` declarations.
2022-05-25 11:32:08 -07:00
Sebastian Ullrich
4a1885f997 chore: update benchmark suite 2022-05-25 18:26:36 +02:00
asdasd1dsadsa
794877c0c8 chore: add option to exclude 'LICENSE' files from 'make install' 2022-05-25 12:39:30 +02:00
Sebastian Ullrich
b97fb23dbe chore: update stage0 2022-05-25 09:48:11 +02:00
Sebastian Ullrich
0a39e9cbdc fix: dynamic quotations should use previous stage by default
@leodemoura as discussed some time ago
2022-05-25 09:46:10 +02:00
Leonardo de Moura
cb32681978 doc: add slide headers to examples 2022-05-23 18:20:37 -07:00
Leonardo de Moura
bf5f107e74 doc: missing NFM examples 2022-05-23 18:04:03 -07:00
Leonardo de Moura
7c427c1ef2 fix: make sure let-expressions do not affect the structural recursion module
This issue has been reported at https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Termination.20check.20not.20preserved.20under.20let.20binding.2E/near/282934378
2022-05-23 13:42:48 -07:00
Leonardo de Moura
655c9fafa4 chore: update stage0 2022-05-23 12:00:10 -07:00
Leonardo de Moura
d05dff078a chore: update stage0 2022-05-23 11:56:59 -07:00
Leonardo de Moura
2fc23a2a2b feat: make sure we can use split to synthesize code 2022-05-23 11:55:57 -07:00
Leonardo de Moura
e552558f2f chore: style 2022-05-23 11:04:29 -07:00
Leonardo de Moura
6ce6b12707 doc: NFM'22 examples 2022-05-22 19:21:30 -07:00
Leonardo de Moura
56cd6c1ff5 fix: we should not use implicit targets when creating the key for the CustomEliminator map 2022-05-20 06:55:23 -07:00
Leonardo de Moura
063c77037f chore: fix typo 2022-05-20 06:44:25 -07:00
E.W.Ayers
8ef0154403 refactor: rpc -> serverRpcMethod 2022-05-19 18:53:19 +02:00
E.W.Ayers
3bdb98e5ee feat: rpc attribute
Functions can now be marked with the `@[rpc]` attribute, which
registers the function as an RpcProcedure that can be used to
communicate with the code editor and infoview.
2022-05-19 18:53:19 +02:00
Sebastian Ullrich
d13fac6f45 doc: update quickstart 2022-05-18 17:43:14 +02:00
Sebastian Ullrich
c3a9831388 doc: document ‹t› 2022-05-18 10:32:06 +02:00
Sebastian Ullrich
1d44c30b3f refactor: simplify log2 termination proof 2022-05-18 10:20:36 +02:00
Sebastian Ullrich
eb170d1f43 fix: compiled string literals containing null bytes 2022-05-17 09:24:34 -07:00
Sebastian Ullrich
1e271c3432 chore: CI: document ridiculous workaround 2022-05-17 17:45:58 +02:00
Sebastian Ullrich
14225b81ce chore: CI: really? 2022-05-17 15:53:33 +02:00
Sebastian Ullrich
a2bf2a4abd fix: info at pattern variables 2022-05-17 06:28:59 -07:00
Sebastian Ullrich
61c7b8b94c chore: format string 2022-05-16 15:14:01 +02:00
Sebastian Ullrich
46df02877d fix: elab info for decreasing_by 2022-05-16 10:20:49 +02:00
Sebastian Ullrich
bfb9dc0697 chore: CI: really do not build nightlies on forks 2022-05-16 09:58:26 +02:00
Sebastian Ullrich
4934104eaf chore: update script/reformat.lean 2022-05-13 11:55:44 +02:00
Wojciech Nawrocki
5cd4bd3552 refactor: auto-derive RpcEncoding 2022-05-12 13:22:37 -07:00
Wojciech Nawrocki
a8cfbb11bf Revert "chore: fix tests"
This reverts commit c6acd968d7.
2022-05-12 13:22:37 -07:00
Wojciech Nawrocki
c81ee908ea chore: update stage0 2022-05-12 13:22:37 -07:00
Wojciech Nawrocki
bea68819c9 feat: support optional RPC fields 2022-05-12 13:22:37 -07:00
Wojciech Nawrocki
dd6528bceb fix: undo incorrect JSON encoding 2022-05-12 13:22:37 -07:00
Leonardo de Moura
f1e9ed2e5a chore: update stage0 2022-05-12 08:48:57 -07:00
Leonardo de Moura
c6acd968d7 chore: fix tests 2022-05-12 08:44:00 -07:00
Leonardo de Moura
9460078dd1 chore: update stage0 2022-05-12 08:39:27 -07:00
Sebastian Ullrich
4e3ddf716e refactor: unnecessary quotation kind 2022-05-12 08:38:09 -07:00
Sebastian Ullrich
75cbb5904e refactor: use syntax quotations 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
7ad1ccab78 feat: use quotation prechecks where possible at FromToJson 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
9296afca12 chore: undo unnecessary change 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
fbb20d465b fix: RpcEncoding tests 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
603a062f1f chore: revert API change 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
63b33424e1 feat: add Widget.Basic 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
460abc4b94 fix: failure in FromToJson 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
0b554f385e feat: RpcEncoding for inductive types 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
c291a78b6a fix: repeated field types in RpcEncoding 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
a19c666f2d feat: add helpers 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
100008ceb1 feat: support generic structure parameters in RpcEncoding 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
72c4717055 chore: remove dead code 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
11e10459bb refactor: move function to PrettyPrinter 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
81b1f1df6e refactor: unify format functions 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
aa2ad384e7 chore: remove old InfoTree ctor 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
b33eb12328 chore: simplify evaluation and use macro scope instead of namespace 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
aa5fe5864a doc: document some Deriving utils 2022-05-12 08:38:09 -07:00
Wojciech Nawrocki
4b3c2b1790 doc: document some meta utilities 2022-05-12 08:38:09 -07:00
Leonardo de Moura
a8032e4173 fix: another mut misbehaving example
```
def mutVariableDo2 (list : List Nat) : Nat := Id.run <| do
  let mut sum := 0
  for _ in list do
    sum := sum.add 1  -- first `sum` was not connected, i.e., it was not highlighted when hovering over the second `sum`
  pure sum
```
2022-05-12 08:26:07 -07:00
Leonardo de Moura
362961912b chore: remove unnecessary variable 2022-05-12 06:44:13 -07:00
Leonardo de Moura
f44a701637 chore: style 2022-05-11 15:32:18 -07:00
Sebastian Ullrich
d03f0b3851 fix: set of chained lexical references 2022-05-11 17:32:06 +02:00
Sebastian Ullrich
23fac14b33 chore: try with fresh cache 2022-05-11 12:31:55 +02:00
Leonardo de Moura
94d2a3ef86 feat: improve error message when failing to infer resulting universe level for inductive datatypes and structures 2022-05-10 18:30:53 -07:00
Leonardo de Moura
c935a3ff6a feat: improve error location for universe level errors at inductive command 2022-05-10 12:50:01 -07:00
Sebastian Ullrich
392640d292 feat: allow keyword-like projection identifiers 2022-05-10 12:25:30 -07:00
Leonardo de Moura
37b2f74404 chore: update stage0 2022-05-10 11:24:10 -07:00
Leonardo de Moura
1d066364f3 chore: update stage0 2022-05-10 11:21:54 -07:00
Leonardo de Moura
f58afaaa43 fix: make sure let _ := val and let _ : type := val are treated at letIdDecl
closes #1114
2022-05-10 06:52:27 -07:00
Sebastian Ullrich
1b51bab4a1 feat: turn on info trees by default 2022-05-10 06:24:31 -07:00
Leonardo de Moura
7ce0471f28 feat: improve binrel% elaborator
It now relies on `binop%` too, and addresses issue reported at
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Regression.20in.20coercion.20inference/near/281737387
2022-05-09 18:39:52 -07:00
Leonardo de Moura
1768067aa0 doc: document elaboration issue
described at
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Regression.20in.20coercion.20inference/near/281737387

TODO: improve `binrel%` elaboration function.
2022-05-09 17:39:24 -07:00
Sebastian Ullrich
ff6537be1b fix: use consistent goal prefix everywhere 2022-05-09 17:49:00 +02:00
Leonardo de Moura
fc03b2fc31 feat: unfold ident,+ 2022-05-09 07:09:53 -07:00
Leonardo de Moura
2680711f6a chore: update stage0 2022-05-09 07:09:53 -07:00
Leonardo de Moura
995d4f0979 chore: prepare for unfold ident,+ 2022-05-09 07:09:22 -07:00
Leonardo de Moura
e729b32b2b feat: unfold should fail if it didn't unfold anything 2022-05-09 06:41:17 -07:00
Leonardo de Moura
4875224bd4 feat: unfold tactic tries to reduce match after unfolding 2022-05-09 06:35:40 -07:00
Leonardo de Moura
ecbc59c8d8 chore: split Notation.lean 2022-05-09 05:20:19 -07:00
Sebastian Ullrich
fa7c35f4f6 doc: normalize tactic doc strings 2022-05-09 10:37:59 +02:00
William Blake
9c72917f5e doc: fix typo gree -> tree 2022-05-09 09:44:48 +02:00
Leonardo de Moura
3cd46888bf fix: check types using default reducibility at synthInstance?
closes #1131
2022-05-08 06:49:14 -07:00
Leonardo de Moura
0fd47fd817 chore: update stage0 2022-05-07 15:52:01 -07:00
Sebastian Ullrich
91991649bc fix: connect occurrences of mutable variable inside and outside for in info tree 2022-05-07 15:50:26 -07:00
Sebastian Ullrich
22f8ea147c fix: propagate position information of variables in do blocks 2022-05-07 15:50:26 -07:00
Sebastian Ullrich
daa9e03e78 fix: combineFvars 2022-05-07 15:50:26 -07:00
Sebastian Ullrich
2f461d201e fix: info tree of let_delayed 2022-05-07 15:50:26 -07:00
François G. Dorais
155b41937a fix: remove unnecessary hypothesis (#1144) 2022-05-07 15:39:37 -07:00
Leonardo de Moura
9043f91d8c fix: if Tactic.Context.recover == false, we must disable "error to sorry" when elaborating terms in tactics
closes #1142
2022-05-07 15:37:12 -07:00
Leonardo de Moura
ab31f9ad5d fix: fixes #1143 2022-05-07 15:27:34 -07:00
Leonardo de Moura
dc1b16c4fb chore: update stage0 2022-05-07 15:10:06 -07:00
Leonardo de Moura
2c8c20d424 feat: add [eliminator] attribute specifying default recursors/eliminators for the cases and induction tactics 2022-05-07 15:09:42 -07:00
Leonardo de Moura
73cb952275 feat: add Hashable (Array α) instance 2022-05-07 15:01:32 -07:00
Leonardo de Moura
b5bcf252ce chore: cleanup 2022-05-07 14:48:22 -07:00
Leonardo de Moura
af5e13e534 feat: improve binop% elaboration function 2022-05-07 10:32:55 -07:00
Leonardo de Moura
38baeaf373 feat: backtrack when applying default instances if subproblems cannot be solved 2022-05-07 09:56:38 -07:00
Leonardo de Moura
8c23bef399 feat: add support for casesOn applications to structural and well-founded recursion modules 2022-05-06 17:12:10 -07:00
Leonardo de Moura
090503cfd5 chore: cleanup 2022-05-06 17:12:10 -07:00
KaseQuark
5ebd6c28db feat: change "⊢" in conv goals to "|" 2022-05-06 09:35:04 +02:00
Leonardo de Moura
7a1c79043e chore: fix test 2022-05-04 15:34:37 -07:00
Leonardo de Moura
dce92c6362 chore: update stage0 2022-05-04 15:32:22 -07:00
Leonardo de Moura
db89750030 chore: update RELEASES.md 2022-05-04 15:31:57 -07:00
Leonardo de Moura
5aaccc8ebb chore: remove OptionM 2022-05-04 15:30:10 -07:00
Leonardo de Moura
eaea5c4773 chore: update stage0 2022-05-04 15:28:49 -07:00
Leonardo de Moura
c65537aea5 feat: Option is a Monad again
TODO: remove `OptionM` after update stage0

see: https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Do.20we.20still.20need.20OptionM.3F/near/279761084
2022-05-04 15:27:42 -07:00
Leonardo de Moura
04d3c6feeb fix: auto implicit behavior on constructors 2022-05-04 15:04:49 -07:00
Leonardo de Moura
a1af8074c9 feat: improve discriminant refinement procedure 2022-05-04 14:46:43 -07:00
Leonardo de Moura
16ed5a3213 fix: erase_irrelevant.cpp
It addresses issue reported at https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/'unreachable'.20code.20was.20reached.20by.20termination.20check/near/281159704
2022-05-04 08:06:59 -07:00
Leonardo de Moura
94b5a9b460 feat: improve split tactic 2022-05-03 17:46:50 -07:00
Gabriel Ebner
88e26b75b0 fix: actually abort with LEAN_ABORT_ON_PANIC
The previous null-pointer dereference was UB and therefore optimized
away.
2022-05-03 09:42:45 -07:00
Sebastian Ullrich
f6e74c677e doc: metaprogramming-arith: deduplicate 2022-05-03 18:38:36 +02:00
Sebastian Ullrich
87431da7b1 doc: metaprogramming-arith: style 2022-05-03 18:38:36 +02:00
Joscha
5749fb1474 fix: search for local refs only in current file
Fixed by adding the identifier's module as an argument to referringTo.
If the ident is RefIdent.const, this is ignored, but if it is
RefIdent.fvar, referringTo limits its search to the ident's module.
2022-05-03 16:53:03 +02:00
Sebastian Ullrich
e76a2a6d9e chore: normalize spelling 2022-05-03 10:26:11 +02:00
Leonardo de Moura
94abfdba6c feat: improve implementedBy errors, and relax type matching test 2022-05-02 08:48:15 -07:00
Leonardo de Moura
fe00dd8f29 fix: missing sanitizeNames at msgToInteractiveAux 2022-05-02 07:35:12 -07:00
Sebastian Ullrich
c755aa81bd fix: properly distinguish between internal and public linker flags 2022-05-02 13:53:52 +02:00
Sebastian Ullrich
2f3396e58a fix: non-termination in deduplication of lexical references 2022-05-02 09:51:14 +02:00
Sebastian Ullrich
09e4c00c68 fix: lexical references through x := e and similar macros 2022-05-01 17:46:05 +02:00
Leonardo de Moura
109363bc7e fix: closes #1132 2022-05-01 08:18:30 -07:00
Leonardo de Moura
4eb2cfec46 feat: make sure case' ... => tac does not use done after tac 2022-05-01 07:30:11 -07:00
Leonardo de Moura
03524305db fix: findTag?
If there is an exact match, return it.
2022-05-01 07:30:11 -07:00
Sebastian Ullrich
a0678b5f6f refactor: rename confusing Reference.isDeclaration field 2022-05-01 16:21:15 +02:00
Sebastian Ullrich
7512f8ab6e chore: CI: pin setup-msys2
https://github.com/msys2/setup-msys2/issues/216
2022-05-01 11:58:58 +02:00
Sebastian Ullrich
952abbf16b chore: remove obsolete workaround 2022-05-01 11:52:53 +02:00
Sebastian Ullrich
4174643dbd perf: optimize withAntiquot parenthesizer
Doesn't look like we'll get rid of the backtracking anytime soon
2022-05-01 11:52:53 +02:00
Leonardo de Moura
fa943d3864 chore: update RELEASES.md 2022-04-29 15:59:34 -07:00
Leonardo de Moura
ee0414b026 chore: update stage0 2022-04-29 15:51:47 -07:00
Leonardo de Moura
862492778a test: add deq_correct test from Zulip 2022-04-29 15:50:40 -07:00
Leonardo de Moura
cddf9ddd95 fix: forallAltTelescope heterogeneous equality support 2022-04-29 15:37:20 -07:00
Leonardo de Moura
c19672e99e fix: basic support for the new discriminant equality encoding at split
TODO: This is a temporary fix. We can do better.
2022-04-29 15:29:39 -07:00
Leonardo de Moura
c241ef61b1 fix: use HEq (if needed) for encoding h : discr equalities 2022-04-29 15:05:48 -07:00
Leonardo de Moura
351f0deae9 feat: add mkEqHEq 2022-04-29 14:31:36 -07:00
Leonardo de Moura
941ad84ece fix: getMkMatcherInputInContext 2022-04-29 12:44:36 -07:00
Leonardo de Moura
95ea0b92ea chore: fix test 2022-04-29 12:40:32 -07:00
Leonardo de Moura
d4d538cad8 fix: counterexample generation for new match encoding 2022-04-29 12:36:53 -07:00
Leonardo de Moura
ec932e389b chore: fix test 2022-04-29 12:30:45 -07:00
Leonardo de Moura
d3bc963e92 chore: update stage0 2022-04-29 12:20:46 -07:00
Leonardo de Moura
6e1c51dd1a feat: splitter proof for new match encoding 2022-04-29 12:19:24 -07:00
Leonardo de Moura
89441aac2a feat: match equation theorem generation for new h : discr notation encoding
TODO: splitter theorem generation still needs to be fixed.
2022-04-29 11:48:25 -07:00
Leonardo de Moura
24417ed466 feat: size, get, get!, getD, and getOp for Subarray 2022-04-29 09:55:45 -07:00
Leonardo de Moura
eac83586c6 chore: remove leftover 2022-04-29 09:10:27 -07:00
Leonardo de Moura
c959c80310 chore: reset local context at correct place 2022-04-29 09:08:44 -07:00
Leonardo de Moura
10d43492ba chore: fix test 2022-04-29 07:17:46 -07:00
Leonardo de Moura
8d9626dab7 feat: delaborate match h : d with ... 2022-04-29 07:17:46 -07:00
Leonardo de Moura
0f7754847d chore: style 2022-04-29 07:17:46 -07:00
Leonardo de Moura
d793d2f0fd feat: adapt elabMatchAltView to handle the new encoding for h : discr = pattern 2022-04-29 07:17:46 -07:00
Leonardo de Moura
7a369848a0 feat: new mkMatcher
TODO: adjust match elaborator
2022-04-29 07:17:46 -07:00
Leonardo de Moura
f4b4b14797 refactor: prepare to handle match h: notation at Meta\Match\Match.lean 2022-04-29 07:17:46 -07:00
Sebastian Ullrich
9b4feb3d13 perf: work around missed TCO 2022-04-29 16:16:09 +02:00
Sebastian Ullrich
b450fb8243 chore: CI: use stable Nix 2022-04-29 16:16:09 +02:00
Sebastian Ullrich
ff4a770c2d feat: annotate match tactic alternatives with expected state 2022-04-29 16:16:09 +02:00
Sebastian Ullrich
39a0de40dd feat: annotate <;> with expected state 2022-04-29 16:16:09 +02:00
Sebastian Ullrich
0a88f68d39 chore: finish with_annotate_state implementation 2022-04-29 16:16:09 +02:00
Sebastian Ullrich
d886a1da72 chore: update stage0 2022-04-29 16:16:09 +02:00
Sebastian Ullrich
db2a912112 feat: with_annotate_state helper tactic 2022-04-29 16:16:09 +02:00
Sebastian Ullrich
a167828b79 fix: refine previous commit's heuristic
Show indented state if there is no outer state that is leading & not indented
relative to the cursor position
2022-04-29 16:16:09 +02:00
Sebastian Ullrich
87b216a8e1 fix: do not show states from tactics indented further than the cursor 2022-04-29 16:16:09 +02:00
Sebastian Ullrich
cc5e7ee731 test: part of #1119 2022-04-29 16:16:09 +02:00
Sebastian Ullrich
b714a32d27 fix: revert "fix: show single final state after tactic combinator"
This reverts commit eb7bf2b272.
2022-04-29 16:16:09 +02:00
Sebastian Ullrich
78bf398830 fix: avoid signal-unsafe fprintf in stack overflow handler 2022-04-29 15:55:11 +02:00
Vincent de Haan
20e16f1c75 doc: add amssymb package to latex example to make it work in all cases 2022-04-28 11:21:12 +02:00
Leonardo de Moura
575b1187c5 feat: add Tactic.Context.recover for controlling error recovery
Moreover, when executing `tac_1 <|> tac_2`, we now disable error
recovery at `tac_1`.

closes #1126 #1127
2022-04-27 10:47:15 -07:00
Leonardo de Moura
ae913efa99 test: collect info view issues 2022-04-27 09:42:18 -07:00
Sebastian Ullrich
829c81d677 fix: skip antiquotations during parser recovery 2022-04-27 10:41:27 +02:00
Sebastian Ullrich
83f331b5e2 parseCommand: use do 2022-04-27 10:41:27 +02:00
Mario Carneiro
f37b700e6e fix: use correct number of none patterns for antiquotation splice 2022-04-27 09:55:27 +02:00
Leonardo de Moura
02d0a89229 chore: simpStar does not make sense for dsimp 2022-04-26 11:26:54 -07:00
Sebastian Ullrich
3d2215c93c doc: clean up syntax ToC 2022-04-26 18:58:45 +02:00
Leonardo de Moura
cae59c6916 chore: remove staging workarounds 2022-04-26 08:23:43 -07:00
Leonardo de Moura
25053594ff chore: update stage0 2022-04-26 08:22:25 -07:00
Leonardo de Moura
6af1da450e feat: disable only eta for classes during TC resolution
closes #1123
2022-04-26 08:20:39 -07:00
Sebastian Ullrich
814f614369 fix: simp attributes and macro scopes 2022-04-26 10:39:02 +02:00
Leonardo de Moura
3cf642688b fix: do not generate equation theorems while processing dsimp arguments 2022-04-25 18:11:32 -07:00
Leonardo de Moura
6bc5433b17 fix: add support for heterogeneous equality at processGenDiseq 2022-04-25 16:56:03 -07:00
Leonardo de Moura
4a4473ff90 chore: update stage0 2022-04-25 16:35:47 -07:00
Leonardo de Moura
40c8db7494 feat: improve argument type mismatch error position, and do not stop at application type mismatch errors 2022-04-25 16:30:40 -07:00
Leonardo de Moura
0c8a6d8977 feat: exists es:term,+ tactic
cc: @fgdorais
2022-04-25 15:35:31 -07:00
Leonardo de Moura
29b340aa36 fix: consume Expr.mdata at congr tactic
fixes #1118
2022-04-25 06:33:32 -07:00
Leonardo de Moura
3ad8dcb7ff fix: nasty interaction between TC resolution and Eta for structures
See
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/.60constructor.60.20and.20.60Applicative.60/near/279984801
2022-04-24 08:19:29 -07:00
Leonardo de Moura
47b379e1bc feat: dsimp! tactic 2022-04-23 18:41:04 -07:00
Leonardo de Moura
342a26a023 feat: dsimp tactic 2022-04-23 18:05:18 -07:00
Leonardo de Moura
13bcbe91cd fix: regression reported at issue #1113
see issue #1113
2022-04-23 15:39:04 -07:00
Leonardo de Moura
4ab57475a0 chore: simplify proofs 2022-04-23 12:47:10 -07:00
Leonardo de Moura
e25a116821 chore: RELEASES.md 2022-04-23 12:16:36 -07:00
Leonardo de Moura
ed12b62e28 fix: InfoTree was missing information for (pseudo) match patterns such as x + 1.
This kind of pattern has to be reduced to a constructor, and the
`PatternWithRef` information was being lost in the process.
2022-04-23 12:08:59 -07:00
Leonardo de Moura
305d8e641c chore: style 2022-04-23 10:47:53 -07:00
Sebastian Ullrich
eb7bf2b272 fix: show single final state after tactic combinator 2022-04-23 17:42:32 +02:00
Sebastian Ullrich
240c5e15e9 fix: show final goal state at end of tactic combinator 2022-04-23 17:15:32 +02:00
Leonardo de Moura
34c75fc443 feat: allow even if the expected type is not available
see issue #1116
2022-04-23 08:00:27 -07:00
Leonardo de Moura
36fad4bba0 fix: do not assign metavariables in the major premise type when trying K 2022-04-23 07:31:51 -07:00
Leonardo de Moura
a82abee1b2 feat: sum of monomials normal form by reflection 2022-04-22 18:51:48 -07:00
Leonardo de Moura
875bf9bf34 fix: apply dsimp at lambda binders
This fixes another regression reported at #1113
2022-04-22 13:10:21 -07:00
Leonardo de Moura
c13ed7c0de fix: regression reported at #1113
See #1113
2022-04-22 11:43:58 -07:00
Leonardo de Moura
864c4c5030 chore: update stage0 2022-04-22 09:53:47 -07:00
Leonardo de Moura
2a2aeec085 feat: LSP semantic token for where and let rec declarations 2022-04-22 09:52:20 -07:00
Sebastian Ullrich
ca3f1a84b0 doc: fix example style 2022-04-22 16:26:16 +02:00
Leonardo de Moura
a5bf0d5ea5 chore: invert setup chapters by making the quickstart the default and the other one "extended setup notes" 2022-04-21 18:09:54 -07:00
Leonardo de Moura
66c82dadc9 fix: the default value for structure fields may now depend on the structure parameters 2022-04-21 17:38:19 -07:00
Leonardo de Moura
09dfd97593 chore: remove temporary workaround 2022-04-21 16:29:08 -07:00
Leonardo de Moura
46dbddabd5 chore: update stage0 2022-04-21 16:27:00 -07:00
Leonardo de Moura
d1f10a2e71 feat: apply rfl theorems at dsimp
closes #1113
2022-04-21 16:26:57 -07:00
Leonardo de Moura
2a0dc1804b feat: improve isRflProof and isRflTheorem
The `Eq.symm` of a `rfl` theorem is a `rfl` theorem, the application
of `rfl` theorem too.
2022-04-21 15:40:38 -07:00
Leonardo de Moura
57c3114875 fix: simpAll and tests
We need another `update stage0` to remove workaround at `AC.lean`
2022-04-21 15:00:07 -07:00
Leonardo de Moura
da33347e9d fix: use defauld reducibility setting at mkImpDepCongrCtx and mkImpCongrCtx 2022-04-21 14:55:29 -07:00
Leonardo de Moura
abc75053b6 chore: update stage0 2022-04-21 13:43:36 -07:00
Leonardo de Moura
f891c5724d feat: track rfl simp theorems
See issue #1113

We need update stage0 before closing the issue.
2022-04-21 13:42:04 -07:00
Leonardo de Moura
0b92195ec8 feat: refine auto bound implicit feature 2022-04-21 10:17:15 -07:00
Leonardo de Moura
d81c124479 chore: update stage0 2022-04-21 08:37:31 -07:00
Leonardo de Moura
4727fd6883 feat: do not hightlight auxiliary declarations used to compile recursive definitions as variables
They are "morally" constants.
2022-04-21 08:11:22 -07:00
Leonardo de Moura
d8ad343885 test: add Expr.eq_of_toPoly_eq 2022-04-20 23:04:29 -07:00
Leonardo de Moura
6bdeb6c9cb test: add support for sub as som.lean 2022-04-20 22:59:55 -07:00
Leonardo de Moura
6e09dfae1e test: simplify sum of monomials 2022-04-20 22:31:52 -07:00
Leonardo de Moura
14bfe57ba8 test: sum of monomials by reflection 2022-04-20 19:19:50 -07:00
Leonardo de Moura
2a36ae4627 feat: add List.le_antisymm 2022-04-20 16:31:25 -07:00
Leonardo de Moura
9852fe3db8 feat: add simp theorems 2022-04-20 16:14:01 -07:00
Leonardo de Moura
bb3fc358c9 feat: add LawfulBEq Int instance 2022-04-20 14:52:41 -07:00
Leonardo de Moura
73076b855c fix: bug at processGenDiseq 2022-04-20 10:46:05 -07:00
Leonardo de Moura
4a18679c92 chore: include problematic match auxiliary declaration name in the error message 2022-04-20 10:46:05 -07:00
Sebastian Ullrich
e1fbfb677e doc: missing file 2022-04-20 19:13:53 +02:00
Sebastian Ullrich
84cc167f95 doc: fix example code & style 2022-04-20 19:05:43 +02:00
Sebastian Ullrich
c354a9f62f doc: link orphan syntax tutorial 2022-04-20 18:49:38 +02:00
Sebastian Ullrich
5f6bbe59ef doc: fold sub-chapters by default 2022-04-20 18:46:30 +02:00
Sebastian Ullrich
b6446902c2 feat: server.stderrAsMessages option
/cc @leodemoura
2022-04-19 22:29:26 +02:00
Leonardo de Moura
597313135a fix: index out of bounds at computeFixedIndexBitMask
closes #1112
2022-04-19 05:21:43 -07:00
Leonardo de Moura
d0ccb73fc9 chore: update stage0 2022-04-19 05:11:19 -07:00
Leonardo de Moura
556ace5cc1 chore: update RELEASES.md 2022-04-18 17:03:01 -07:00
Leonardo de Moura
4848ad4869 feat: implement autoUnfold at simp
Right now, it only supports the following kind of definitions
- Recursive definitions that support smart unfolding.
- Non-recursive definitions where the body is a match-expression. This
kind of definition is only unfolded if the match can be reduced.
2022-04-18 16:51:52 -07:00
Leonardo de Moura
f87066a0a5 chore: update stage0 2022-04-18 16:01:22 -07:00
Leonardo de Moura
18832ad91c feat: add autoUnfold to Simp.Config
Add macros for conveniently setting `arith` and `autoUnfold`.
2022-04-18 15:59:30 -07:00
Leonardo de Moura
470d0077ca chore: update stage0 2022-04-18 14:57:02 -07:00
Leonardo de Moura
bb2df569bc fix: bug at declare_config_elab 2022-04-18 14:56:22 -07:00
Leonardo de Moura
e69e469a37 chore: update test 2022-04-18 11:56:46 -07:00
Leonardo de Moura
e6aee1e463 feat: make sure cases and induction alternatives are processed using the order provided by the user
Motivation: improve the effectiveness of the `save` and `checkpoint` tactics.
2022-04-18 11:45:36 -07:00
Leonardo de Moura
822375aaff chore: ensure _ alternative is the last one in the cases and induction tactics 2022-04-18 11:18:03 -07:00
Leonardo de Moura
5599cefe2e feat: add sleep tactic for debugging purposes 2022-04-18 09:53:45 -07:00
Leonardo de Moura
d9f007e4dd fix: tactic cache corruption 2022-04-17 15:52:21 -07:00
Leonardo de Moura
607a590238 test: pge example 2022-04-17 15:17:28 -07:00
Leonardo de Moura
40129203b2 chore: update RELEASES.md 2022-04-17 13:55:46 -07:00
Leonardo de Moura
d4183cf646 feat: add option tactic.dbg_cache 2022-04-17 13:47:28 -07:00
Leonardo de Moura
4a303ec214 feat: include tactic position in the cache key 2022-04-17 13:47:12 -07:00
Leonardo de Moura
deab1ebc56 feat: add save tactic
It is a more convenient way of creating checkpoints.
2022-04-17 08:46:08 -07:00
Leonardo de Moura
fa16a96692 chore: avoid nested noImplicitLambda annotations 2022-04-17 08:09:10 -07:00
Leonardo de Moura
726b735c6d fix: using invalid name generator at ContextInfo.runMetaM
Already used `MVarId`s were being "reused" potentially creating cyclic
metavar assignment. See issue #1031 for an example.

closes #1031
2022-04-15 18:42:34 -07:00
Leonardo de Moura
7fc139fdb0 chore: add doc-string for tactics 2022-04-15 14:19:03 -07:00
Leonardo de Moura
d4f514b964 chore: update stage0 2022-04-15 13:49:51 -07:00
Leonardo de Moura
7995cb071f chore: add assertions to make sure TagDeclarationExtension and MapDeclarationExtension are not being misused
see #1111
2022-04-15 13:49:35 -07:00
Sebastian Ullrich
7797fa3e2d fix: fun (x ...) ... should not be treated as a pattern 2022-04-15 10:00:26 -07:00
Leonardo de Moura
bc7f4fd02b test: hasCSimpAttribute 2022-04-15 09:55:10 -07:00
Leonardo de Moura
33a7f75599 chore: update stage0 2022-04-15 09:46:23 -07:00
Leonardo de Moura
a57403be6e feat: add hasCSimpAttribute 2022-04-15 09:44:50 -07:00
Ed Ayers
d8e2d58da7 doc: InfoTree code review
Co-authored-by: Wojciech Nawrocki <wjnawrocki+gh@protonmail.com>
2022-04-15 09:07:35 -07:00
E.W.Ayers
7d128c17dc doc: #1107 review 2022-04-15 09:04:28 -07:00
E.W.Ayers
9598e39c82 doc: InfoTree docstrings 2022-04-15 09:04:26 -07:00
Sebastian Ullrich
458da0e27b chore: update LeanInk 2022-04-15 08:53:34 -07:00
E.W.Ayers
06e8cf5200 fix: allow non-leaf custom info
At the moment InfoTree has a constructor ofJson but this means that
you can't have a non-leaf ofJson. It would be better to have `ofJson` be a constructor of `Info`.
This is what this PR does.
2022-04-15 08:53:34 -07:00
Leonardo de Moura
4aee759ded fix: make sure rfl is an extensible tactic
closes #1109
2022-04-15 08:51:05 -07:00
Sebastian Ullrich
f98b6a3bb1 fix: fall-out from syntax kind lookup change 2022-04-15 08:50:46 -07:00
Sebastian Ullrich
a2baf2cb96 refactor: split term/command quotations 2022-04-15 08:50:46 -07:00
Sebastian Ullrich
ca8fdcaa0c chore: update stage0 2022-04-15 08:50:46 -07:00
Sebastian Ullrich
e1fbc04c3b chore: accept unregistered syntax kinds in stage 1 2022-04-15 08:50:46 -07:00
E.W.Ayers
712967c6f6 refactor: registerRpcProcedure 2022-04-13 13:23:04 -07:00
Wojciech Nawrocki
d649fc9159 fix: RPC error message 2022-04-13 13:23:04 -07:00
Wojciech Nawrocki
367b0fc80f doc: note persistent exts are sometimes needed 2022-04-13 13:23:04 -07:00
E.W.Ayers
30dfabb2c7 fix: userRpcProcedures uses a persistent env ext 2022-04-13 13:23:04 -07:00
Leonardo de Moura
081dff288f fix: debug build 2022-04-13 13:12:53 -07:00
Leonardo de Moura
f875c2d107 chore: update release notes 2022-04-13 10:33:25 -07:00
Leonardo de Moura
bcb9c2c2a3 chore: fix test 2022-04-13 10:27:59 -07:00
Leonardo de Moura
f2c3685e83 chore: update stage0 2022-04-13 10:20:41 -07:00
Leonardo de Moura
8d2d0b3fbe chore: remove {} from structure command 2022-04-13 10:19:00 -07:00
Leonardo de Moura
efb859013e chore: ignore {} annotations at mk_projections 2022-04-13 10:16:41 -07:00
Leonardo de Moura
e00550c57e chore: remove {} occurrences 2022-04-13 10:14:51 -07:00
Leonardo de Moura
3d9439f3c9 chore: missing annotation 2022-04-13 09:03:58 -07:00
Leonardo de Moura
9126d33dda doc: update release notes 2022-04-13 09:01:55 -07:00
Leonardo de Moura
b267a4b288 chore: update stage0 2022-04-13 08:49:15 -07:00
Leonardo de Moura
bd35e8a2be chore: remove {} from ctor parser 2022-04-13 08:47:21 -07:00
Leonardo de Moura
3e0a975e9c chore: fix test 2022-04-13 08:37:34 -07:00
Leonardo de Moura
1f4039a25d chore: remove {} from Eq.refl and HEq.refl 2022-04-13 08:35:02 -07:00
Leonardo de Moura
18868cbaba chore: update stage0 2022-04-13 08:33:14 -07:00
Leonardo de Moura
f098b1c291 test: for regression from last year's course at KIT 2022-04-13 08:31:43 -07:00
Leonardo de Moura
dbf5366704 feat: ignore {} annotation at constructors 2022-04-13 08:30:21 -07:00
Leonardo de Moura
2ec8385767 fix: isDomainDefEq 2022-04-13 07:54:47 -07:00
Leonardo de Moura
600769811e fix: bug at fixedIndicesToParams 2022-04-13 07:33:32 -07:00
Leonardo de Moura
3bdb385c19 fix: make sure "eta for structures" in the elaborator uses projection functions if available 2022-04-11 19:23:10 -07:00
Leonardo de Moura
1add9b814b chore: style 2022-04-11 18:48:09 -07:00
Leonardo de Moura
3de607193f fix: withoutModifyingStateWithInfoAndMessagesImpl
Make sure it does not produced a corrupted `InfoTree`.
2022-04-11 16:57:55 -07:00
Leonardo de Moura
9f8dd99ccd fix: macro declare_config_elab was corrupting the info tree 2022-04-11 16:49:56 -07:00
Leonardo de Moura
e49179c807 fix: simp at local declaration should not create an auxiliary declaration when result is definitionally equal 2022-04-11 07:54:15 -07:00
Leonardo de Moura
fb64a4ccc0 fix: unfold should not create an auxiliary declaration when result is definitionally equal
This commit fixes an issue reported on Zulip
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Unfolding.20the.20type.20of.20a.20variable.20creates.20a.20new.20variable
2022-04-11 07:54:15 -07:00
larsk21
7cf4642d1b fix: apply workspace symbol limit after sorting by score 2022-04-11 16:08:55 +02:00
larsk21
235b6d8f69 fix: remove unnecessary fuzzy scoring rule 2022-04-11 16:08:55 +02:00
Jannis Limperg
5ff8f64255 feat: add IO.monoNanosNow 2022-04-11 12:16:20 +02:00
Jannis Limperg
6459ccc43c fix: prevent overflow in lean_io_mono_ms_now 2022-04-11 12:16:20 +02:00
Leonardo de Moura
c2c2783f32 feat: improve dot name resolution by lazily unfolding resulting type
See new test to understand issue being fixed by this commit.
2022-04-10 14:37:27 -07:00
Leonardo de Moura
ed85a68550 chore: missing backtick 2022-04-10 11:11:51 -07:00
Leonardo de Moura
e4304ea1de fix: always save completion info at resolveName
See new test.
2022-04-10 08:00:03 -07:00
Leonardo de Moura
348037abbf chore: move states35 to bench directory
@Kha It breaks in the CI in debug mode (stack overflow).
I think we have a mechanism for skipping some tests in debug mode, but
I forgot how it works.
2022-04-09 15:46:28 -07:00
Leonardo de Moura
8b53cc8dbb chore: update RELEASES.md 2022-04-09 15:39:40 -07:00
Leonardo de Moura
4d077214f9 feat: jump to definition for match pattern variables 2022-04-09 15:36:42 -07:00
Leonardo de Moura
1db11ed5c7 test: native_decide with 35 states 2022-04-09 14:48:53 -07:00
Leonardo de Moura
86bd70ac62 test: native_decide 2022-04-09 14:41:22 -07:00
Marcus Rossel
a8db183d5c chore: typos 2022-04-09 13:02:01 -07:00
Leonardo de Moura
027fec76da chore: update stage0 2022-04-09 12:25:43 -07:00
Leonardo de Moura
4374ec4ad8 perf: use Kernel isDefEq for ground terms
`state8.lean` now takes 0.29s. It was 0.37s.
2022-04-09 12:24:20 -07:00
Leonardo de Moura
e3dcce5320 chore: remove temporary workarounds 2022-04-09 12:13:37 -07:00
Leonardo de Moura
948c3c0ec4 chore: update stage0 2022-04-09 12:12:17 -07:00
Leonardo de Moura
4dd2b26e06 fix: rfl error message and corner case
The new `rfl` slightly improves the performance for `rfl` proofs of
ground terms.
Example: `state8.lean` now takes 0.37s. It was 0.52s.
2022-04-09 12:08:04 -07:00
Leonardo de Moura
628e33bf8a feat: activate new rfl tactic implementation 2022-04-09 12:01:56 -07:00
Leonardo de Moura
47e7e03f79 chore: update stage0 2022-04-09 11:58:12 -07:00
Leonardo de Moura
03f6b87647 feat: add hand-written rfl tactic
It requires update stage0
2022-04-09 11:57:27 -07:00
Leonardo de Moura
298281baaf perf: skip logUnassignedUsingErrorInfos if pendingMVarIds is empty
`state8.lean` now takes 0.52s. It was 0.76s.
2022-04-09 10:45:52 -07:00
Leonardo de Moura
7d99f6f555 perf: isClassQuick? was incorrectly producing undef
Then `isClassExpensive?` was being invoked too often. In some
benchmarks the performance hit was substantial. For example,
in the new test `state8.lean`. The runtime on my machine went from 2s
to 0.76s.
2022-04-09 10:38:49 -07:00
Leonardo de Moura
6e02514eee chore: style 2022-04-09 10:27:31 -07:00
Leonardo de Moura
417421dbae fix: auto completion when autoBoundImplicit is active 2022-04-09 09:11:45 -07:00
Leonardo de Moura
87e6581e6b fix: constructor elaboration
fixes #1098
2022-04-08 18:19:06 -07:00
Leonardo de Moura
1c236a0d43 chore: update stage0 2022-04-08 15:05:38 -07:00
Leonardo de Moura
3cf425ba52 fix: pattern hover information
We annotate patterns with the corresponding `Syntax` during
elaboration, and do not populate the info tree. Reason: the set of
pattern variables is not known during pattern elaboration.
2022-04-08 15:03:42 -07:00
Leonardo de Moura
4793c7e734 feat: add isAppOfArity variant that skips Expr.mdata 2022-04-08 15:01:57 -07:00
Leonardo de Moura
152eff5cea chore: missing double ticks 2022-04-08 15:01:57 -07:00
Leonardo de Moura
ea682830d1 refactor: change addTermInfo type 2022-04-08 15:01:57 -07:00
Sebastian Ullrich
74435013f4 chore: remove now-broken workarounds 2022-04-08 15:53:58 +02:00
Sebastian Ullrich
51d6a75a0f chore: update stage0 2022-04-08 15:53:58 +02:00
Sebastian Ullrich
4aed79a13e feat: less strict, hopefully more helpful syntax ident matching semantics 2022-04-08 15:53:58 +02:00
Leonardo de Moura
5d8b4f33c0 feat: improve binder names introduced by the match discriminant refinement feature 2022-04-08 06:49:09 -07:00
Leonardo de Moura
099fba43d3 chore: remove trace[Meta.debug] leftovers 2022-04-08 06:49:09 -07:00
E.W.Ayers
917fa74366 doc: docstrings for decls and attributes
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2022-04-08 04:19:38 -07:00
Leonardo de Moura
cec0f81926 chore: add instantiateMVars 2022-04-07 18:46:45 -07:00
Leonardo de Moura
37b321229f feat: make sure hover information does not include @ for constants 2022-04-07 18:40:04 -07:00
Leonardo de Moura
55989c25fc chore: remove unnecessary args 2022-04-07 18:19:15 -07:00
Leonardo de Moura
de2e2447d2 chore: style 2022-04-07 17:35:05 -07:00
Leonardo de Moura
dcb88d969a feat: improve auto implicit binder names in definitions/theorems 2022-04-07 14:46:59 -07:00
Leonardo de Moura
cd0d7e676f chore: rename renameMVar => setMVarUserName 2022-04-07 13:50:58 -07:00
Leonardo de Moura
00c4524e80 chore: register Elab.induction trace class 2022-04-07 13:22:40 -07:00
Leonardo de Moura
c26e968c24 chore: style 2022-04-07 11:25:45 -07:00
Leonardo de Moura
fa9b0f6c7e feat: remove space before propositions with inaccessible names 2022-04-07 07:54:50 -07:00
Leonardo de Moura
9de6961906 chore: to doc string 2022-04-07 07:29:23 -07:00
Leonardo de Moura
27cd678717 doc: improve contradiction doc string 2022-04-06 19:27:23 -07:00
Leonardo de Moura
e5b8d94a65 chore: remove unnecessary annotation 2022-04-06 16:38:16 -07:00
Leonardo de Moura
5b15a97d72 chore: break long lines 2022-04-06 16:37:38 -07:00
Leonardo de Moura
39093188bf chore: use cdot 2022-04-06 16:32:20 -07:00
Leonardo de Moura
911ed750ff doc: document 2022-04-06 16:30:02 -07:00
Leonardo de Moura
005f964749 feat: save info at renameInaccessibles
We now have info variables introduced by the `next` and `case` tactics
2022-04-06 16:16:20 -07:00
Leonardo de Moura
317492d207 test: add test for Lean 3 refine bug reported on Zulip
https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/.60refine.60.20bug.20.3F/near/278031110
2022-04-06 16:04:17 -07:00
Leonardo de Moura
847f5b21a6 feat: save info for cases and induction alt vars 2022-04-06 15:53:58 -07:00
Leonardo de Moura
cd82a24ca9 chore: avoid "denote" overloading
It the overload does not affect elaboration, but pollutes the info view.
2022-04-06 15:00:13 -07:00
Leonardo de Moura
36e032cf94 chore: fix test 2022-04-06 14:55:27 -07:00
Leonardo de Moura
0bfcf434ac fix: jump to definition inside of a mutually inductive declaration 2022-04-06 14:43:30 -07:00
Leonardo de Moura
1107705525 fix: jump to definition inside recursive definitions was not working on VS Code
Remark: it was working on Emacs.
2022-04-06 14:27:49 -07:00
Leonardo de Moura
574927ab0d fix: jump to definition for recursive declarations 2022-04-06 13:01:16 -07:00
Leonardo de Moura
d380808930 fix: generalize if target is a let-declaration 2022-04-06 11:08:41 -07:00
Sebastian Ullrich
6841f37662 chore: update stage0 2022-04-06 19:43:07 +02:00
Sebastian Ullrich
24697026e8 feat: always accept antiquotations, simplify quotDepth code 2022-04-06 19:43:07 +02:00
Sebastian Ullrich
8f2f6bc17d doc: adjust alectryon.css a little 2022-04-06 09:06:49 -07:00
Sebastian Ullrich
020fb82888 doc: clean up examples markup 2022-04-06 09:06:49 -07:00
Sebastian Ullrich
2aaac3f94b doc: embed examples into doc book 2022-04-06 09:06:49 -07:00
Sebastian Ullrich
e10e664cc1 chore: typos 2022-04-06 10:21:53 +02:00
Sebastian Ullrich
3cf2afa42e refactor: clean up parsers using withAnonymousAntiquot := false 2022-04-06 10:21:53 +02:00
Sebastian Ullrich
dfd469743c chore: update stage0 2022-04-06 10:21:53 +02:00
Sebastian Ullrich
ffee6676ef feat: allow adjusting anonymous antiquot generation at leading_parser 2022-04-06 10:21:53 +02:00
Sebastian Ullrich
99464c352e chore: remove restriction on leading/trailing_parser macros
I don't think we quote any parsers right now
2022-04-06 10:21:53 +02:00
Sebastian Ullrich
7460878e05 chore: define WIN32_LEAN_AND_MEAN 2022-04-06 09:38:19 +02:00
Leonardo de Moura
149cd1ee82 chore: fix test 2022-04-05 21:04:55 -07:00
Leonardo de Moura
058aea8922 fix: withSaveInfoContext at Inductive.lean
It was in the context of `withInductiveLocalDecls`. This introduced
unnecessary `_root_` in the info view and hover information.

For example, when hovering over
```lean
inductive Ty where
  | int
  | bool
  | fn (a r : Ty)
```
We would get `Ty.int : _root_.Ty` when hovering over the `int`.
2022-04-05 20:58:06 -07:00
Leonardo de Moura
f5583d7771 chore: update stage0 2022-04-05 20:52:30 -07:00
Leonardo de Moura
7c5575631a feat: remove _tmp_ind_univ_param elaboration hack
The new approach produces better type information in the "info view" when
hovering over inductive declarations.
2022-04-05 20:51:15 -07:00
Leonardo de Moura
27e07d1b25 fix: remove auxiliary discriminants before elaborating patterns 2022-04-05 19:37:56 -07:00
Leonardo de Moura
d65691626c chore: update stage0 2022-04-05 17:38:43 -07:00
Leonardo de Moura
eae4b92b0d feat: use sorry if failed to synthesize default element for unsafe constant 2022-04-05 16:52:54 -07:00
Sebastian Ullrich
d2c626e158 doc: refine development manual 2022-04-05 16:03:24 +02:00
Leonardo de Moura
18707692a8 doc: add doc strings to some tactics 2022-04-05 06:27:09 -07:00
Leonardo de Moura
16523647b8 doc: add doc strings to some tactics 2022-04-05 06:27:09 -07:00
Sebastian Ullrich
adcdd16d7a doc: include missing chapter 2022-04-04 17:56:19 +02:00
Leonardo de Moura
6aee3fb304 chore: fix broken links 2022-04-03 10:32:00 -07:00
Leonardo de Moura
5470100830 feat: better binder names at reorderCtorArgs 2022-04-03 10:03:47 -07:00
Leonardo de Moura
a8ee6029c2 chore: remove workaround from example 2022-04-03 09:25:47 -07:00
Leonardo de Moura
61ae72330f feat: improve universe level contraint checks in inductive datatype constructors 2022-04-03 09:19:22 -07:00
Leonardo de Moura
3ee8ceafb4 feat: better error message when constructor parameter universe level is too big 2022-04-03 08:37:38 -07:00
Leonardo de Moura
ef8fecff79 feat: add Level.geq 2022-04-03 08:18:14 -07:00
Leonardo de Moura
310961cc35 chore: add scaffolding for checking ctor universe params 2022-04-03 07:33:02 -07:00
Leonardo de Moura
743f6dd3a2 chore: cleanup 2022-04-03 06:56:27 -07:00
Leonardo de Moura
ca9b494e4d chore: use specialize tactic 2022-04-02 19:35:36 -07:00
Leonardo de Moura
d7abecd07d test: addDecorations without partial 2022-04-02 19:08:21 -07:00
Leonardo de Moura
c873ad6ef3 test: recursive function on Syntax without partial 2022-04-02 18:43:45 -07:00
Leonardo de Moura
9d55d7bf9e feat: add helper tactic for applying List.sizeOf_lt_of_mem in termination proofs 2022-04-02 18:38:55 -07:00
Leonardo de Moura
64cfbc1ae3 feat: add helper tactic for applying sizeOf (a.get i) < sizeOf a automatically in termination proofs 2022-04-02 18:29:41 -07:00
Leonardo de Moura
562af50191 feat: add ForIn' instance for Range 2022-04-02 18:22:21 -07:00
Leonardo de Moura
2c7c7471db feat: add case' tactic for writing macros
It is similar to `case` but does not admit goal in case of failure.
This is useful for writing macros.
2022-04-02 17:54:06 -07:00
Leonardo de Moura
443dd79a02 feat: sizeOf theorems for Lean.Name 2022-04-02 17:09:55 -07:00
Leonardo de Moura
03ec8cb30b feat: missing sizeOf theorems for Array.get and List.get 2022-04-02 16:04:46 -07:00
Leonardo de Moura
9f29d7ecb7 feat: add stop tactic macro 2022-04-02 15:39:03 -07:00
Leonardo de Moura
3d4e6282b7 chore: fix link to examples 2022-04-02 15:29:12 -07:00
Leonardo de Moura
78007be772 test: for Lean 3 hover issue reported on Zulip 2022-04-02 15:21:24 -07:00
Leonardo de Moura
4fa5f50559 feat: implement TODO at "fixed indices to parameters"
The missing feature (TODO in the code) is needed for the `BinTree` example.
2022-04-02 14:37:24 -07:00
Leonardo de Moura
9fe5458077 feat: do not display inaccessible proposition names if they do not have forward dependencies
Even if `pp.inaccessibleNames = true`
2022-04-02 13:15:17 -07:00
Leonardo de Moura
95bd55bc21 chore: fix typo and remove unnecessary discriminant 2022-04-02 13:15:17 -07:00
Sebastian Ullrich
4fcc7c78dd chore: update LeanInk 2022-04-02 18:13:42 +02:00
Leonardo de Moura
d65ceafc99 chore: break long lines 2022-04-02 07:54:40 -07:00
Leonardo de Moura
9ee3cb642a chore: formatting 2022-04-02 07:53:20 -07:00
Leonardo de Moura
e4fb9c8f47 chore: break long lines 2022-04-02 07:50:27 -07:00
Leonardo de Moura
375692cb92 doc: explain attribute [local simp] 2022-04-02 07:46:32 -07:00
Leonardo de Moura
16649beb19 doc: explain details 2022-04-02 07:39:07 -07:00
Leonardo de Moura
dee5dbca98 chore: cleanup example 2022-04-02 07:13:46 -07:00
Leonardo de Moura
7f00352d33 chore: backtick issue in documentation 2022-04-02 06:55:23 -07:00
Leonardo de Moura
e058fe65a9 feat: make the hypothesis name optional in the by_cases tactic 2022-04-01 19:36:13 -07:00
Leonardo de Moura
ed935ed7a7 doc: binary search trees 2022-04-01 19:30:28 -07:00
Leonardo de Moura
8636594dac chore: add [simp] to Nat.lt_irrefl 2022-04-01 18:50:32 -07:00
Leonardo de Moura
be014b1fc9 fix: dotted notation corner case 2022-04-01 18:20:44 -07:00
Leonardo de Moura
cfb4e306f7 refactor: replace length_dropLast theorem 2022-04-01 16:44:24 -07:00
Leonardo de Moura
2ec40e91da chore: update stage0 2022-04-01 15:48:09 -07:00
Leonardo de Moura
a926cd1698 fix: mkUnfoldProof
The hypotheses in an equation theorem may depend on each other
2022-04-01 15:47:24 -07:00
Leonardo de Moura
4a0f68de83 fix: split tactic issue 2022-04-01 15:47:24 -07:00
Leonardo de Moura
ea8f31144e feat: add predicate to generalize tactic to select subterms to be generalized 2022-04-01 15:47:24 -07:00
Sebastian Ullrich
524dc5d47c chore: Nix: update Nixpkgs 2022-04-02 00:08:24 +02:00
Leonardo de Moura
d473cc5a4c chore: update release notes for issue #1090
closes #1090
2022-04-01 11:38:50 -07:00
Leonardo de Moura
0241d7c197 chore: fix tests 2022-04-01 11:34:50 -07:00
Leonardo de Moura
f45712ce74 chore: update stage0 2022-04-01 11:29:09 -07:00
Leonardo de Moura
fdd1cb5751 chore: remove workarounds for #1090 2022-04-01 11:28:17 -07:00
Leonardo de Moura
48a3668780 chore: fix repo 2022-04-01 11:24:30 -07:00
Leonardo de Moura
16b2237d2d chore: update stage0 2022-04-01 11:24:22 -07:00
Leonardo de Moura
799c701f56 fix: inconsistency between syntax and kind names
TODO: remove staging workarounds

see #1090
2022-04-01 11:20:16 -07:00
Leonardo de Moura
b6cc3c959b chore: update stage0 2022-04-01 11:14:47 -07:00
Leonardo de Moura
68acfc7fb9 chore: prepare for #1090 2022-04-01 11:11:28 -07:00
Leonardo de Moura
8dddb0ddc7 chore: update stage0 2022-04-01 09:37:52 -07:00
Leonardo de Moura
09de67780f chore: prepare for #1090 2022-04-01 09:35:06 -07:00
Leonardo de Moura
414f5596a6 test: Nat.binrec example 2022-04-01 08:29:44 -07:00
Leonardo de Moura
d1022e5587 chore: add Nat.div_add_mod 2022-04-01 08:20:00 -07:00
Leonardo de Moura
92382ea47b fix: checkpoint 2022-04-01 05:53:18 -07:00
E.W.Ayers
9fdb7429d4 doc: edits to MonadControl 2022-04-01 10:06:58 +02:00
E.W.Ayers
4c2fedae50 doc: fix @Kha's issues with MonadControl 2022-04-01 10:06:58 +02:00
Leonardo de Moura
4c9c62752e feat: improve checkpoint tactic 2022-03-31 20:51:53 -07:00
Leonardo de Moura
23f41fddb3 feat: basic tactic cache
TODO: move `IO.Ref` to command
2022-03-31 19:53:03 -07:00
Leonardo de Moura
059459b097 fix: occurs check at refine tactic 2022-03-31 18:08:05 -07:00
Leonardo de Moura
87db7a9115 chore: style 2022-03-31 17:33:56 -07:00
Leonardo de Moura
096e4eb6d0 fix: equation generation for nested recursive definitions
The issue was raised on Zulip. The issue is triggered in
declarations containing overlapping patterns and nested recursive
definitions occurring as the discriminant of `match`-expressions.
Recall that Lean 4 generates conditional equations for declarations
containing overlapping patterns.
To address the issue we had to "fold" `WellFounded.fix` applications
back as recursive applications of the functions being defined.

The new test exposes the issue.
2022-03-31 17:04:06 -07:00
Leonardo de Moura
6652d2665d chore: remove old comment 2022-03-31 15:59:31 -07:00
Leonardo de Moura
0ce967ad90 chore: update stage0 2022-03-31 14:53:37 -07:00
Leonardo de Moura
d21e62ecb7 refactor: custom simpMatch for WF module
It is just the skeleton right now.
2022-03-31 14:51:07 -07:00
Leonardo de Moura
1ab57d4fd4 feat: store fixedPrefixSize at WF.EqnInfo 2022-03-31 14:47:52 -07:00
Leonardo de Moura
734902bd3c test: add split list example from Zulip without sorrys 2022-03-31 13:03:58 -07:00
Leonardo de Moura
23f3de5061 chore: proper trace message class 2022-03-31 11:04:42 -07:00
Leonardo de Moura
2bd04285f8 fix: #1087
This commit is using the easy fix described at issue #1087.
Hopefully the performance overhead is small.

closes #1087
2022-03-30 18:48:02 -07:00
Leonardo de Moura
63b9060ce9 chore: fix comments 2022-03-30 16:23:06 -07:00
Leonardo de Moura
3dd0c84c4d chore: enforce naming convetion for tactics 2022-03-30 16:19:05 -07:00
Leonardo de Moura
df063a47fa chore: fix link 2022-03-30 13:44:22 -07:00
Leonardo de Moura
a509b0c615 test: Sign 2022-03-30 13:33:29 -07:00
Leonardo de Moura
1a8840330f test: add test for example that does not work in Lean3
cc @eric-wieser
2022-03-30 12:59:55 -07:00
Leonardo de Moura
e53e088be8 test: make it clear the proofs hold by reflexivity 2022-03-30 12:40:30 -07:00
Leonardo de Moura
6056a4cbfa test: stars_and_bars 2022-03-30 12:38:05 -07:00
Leonardo de Moura
b6ce9fa4b1 doc: add palindromes.lean 2022-03-30 11:22:58 -07:00
Leonardo de Moura
df3a8eb126 feat: add helper List.append simp theorems 2022-03-30 11:11:03 -07:00
Leonardo de Moura
c9926b3a8b chore: update stage0 2022-03-29 18:53:47 -07:00
Leonardo de Moura
46ce3013d0 feat: cleanup local context before elaborating match alternatives RHS 2022-03-29 18:52:07 -07:00
Leonardo de Moura
815364768d chore: update stage0 2022-03-29 15:57:45 -07:00
E.W.Ayers
00151f39a1 doc: explain MonadControl 2022-03-29 15:55:08 -07:00
Leonardo de Moura
d1e4712038 fix: smart unfolding
See new comment to understand the issue.

closes #1081
2022-03-29 15:49:14 -07:00
Leonardo de Moura
a8bb7fab93 fix: typo at findRecArg
The code was not traversing the indices if the datatype has parameters
2022-03-29 12:12:43 -07:00
Leonardo de Moura
86432f1833 feat: improve let-pattern and have-pattern macro expansion 2022-03-29 07:33:22 -07:00
Sebastian Ullrich
6dfddbe2e7 feat: quotation precheck for choice nodes 2022-03-29 10:50:11 +02:00
Leonardo de Moura
c7321e0061 chore: remove revert hack from example 2022-03-28 17:18:36 -07:00
Leonardo de Moura
a06cd40e29 feat: improve match expression support at simp 2022-03-28 17:17:01 -07:00
Leonardo de Moura
5ca9b49235 chore: cleanup proof 2022-03-28 14:58:02 -07:00
Leonardo de Moura
2a37f53fca chore: fix core library 2022-03-28 14:32:04 -07:00
Leonardo de Moura
21f7c297e6 chore: update stage0 2022-03-28 14:30:35 -07:00
Leonardo de Moura
3c964f3b9f feat: substitute auxiliary equations introduced by the split tactic 2022-03-28 14:29:28 -07:00
Leonardo de Moura
314bd3ae4c fix: simpH? at match expression equation theorem generator
closes #1080
2022-03-28 12:48:54 -07:00
Leonardo de Moura
2dea5471da feat: add support for HEq to the subst tactic 2022-03-28 12:23:55 -07:00
Leonardo de Moura
334f4f6c85 test: for issue #1079
The error reported on issue #1079 does not happen in the master branch.

closes #1079
2022-03-28 07:19:55 -07:00
Leonardo de Moura
4e008cf8b7 chore: move to tests 2022-03-27 14:57:33 -07:00
Leonardo de Moura
4801b37cfb fix: exfalso 2022-03-27 14:56:24 -07:00
Leonardo de Moura
a2c9b6a8be chore: rename Substate => State.le 2022-03-27 09:30:55 -07:00
Leonardo de Moura
3fe7db1bbf chore: remove dead theorem 2022-03-27 09:15:55 -07:00
Leonardo de Moura
b2ef678199 doc: constant propagation for simple imperative language 2022-03-27 09:02:37 -07:00
Leonardo de Moura
3b7c3c0017 chore: add TODO's 2022-03-26 18:59:43 -07:00
Leonardo de Moura
11ed51dcb2 doc: example for the tutorial 2022-03-26 18:52:53 -07:00
Sebastian Ullrich
85c7772f4c doc: fix ReST markup 2022-03-26 22:50:04 +01:00
Sebastian Ullrich
bef34e30e7 feat: Nix: render examples using LeanInk+Alectryon 2022-03-26 22:50:04 +01:00
Sebastian Ullrich
282147631f chore: Nix: add LeanInk + Alectyron to docs flake 2022-03-26 22:50:04 +01:00
Sebastian Ullrich
19925f8ec1 chore: Nix: move docs build into sub-flake
workflow is not ideal right now because of poor support for sub-flakes,
but I also don't want the doc input in the main flake...
2022-03-26 22:50:04 +01:00
Sebastian Ullrich
4a9bc88a4e chore: fix USE_GMP=OFF by removing GMP linking customization 2022-03-26 16:29:52 +01:00
Sebastian Ullrich
1949b3f676 chore: CI: propagate prepare-llvm failures 2022-03-26 16:29:52 +01:00
Sebastian Ullrich
7ce5b0c4ff feat: CI: build darwin_aarch64 2022-03-26 16:29:52 +01:00
Wojciech Nawrocki
96770b4d83 refactor: remove some code duplication 2022-03-26 06:26:41 -07:00
Wojciech Nawrocki
9223bf3640 feat: environment extension for RPC procedures 2022-03-26 06:26:41 -07:00
Sebastian Ullrich
e3a652de98 chore: CI: fix Linux/aarch64 tarball name, remove cpack config 2022-03-26 10:40:43 +01:00
Leonardo de Moura
c69b4d1f8d chore: update stage0 2022-03-25 19:15:45 -07:00
Leonardo de Moura
a2e467eb32 fix: mkEqnTypes
stop as soon as `lhs` and `rhs` are definitionally equal, and avoid
unnecessary case analysis.

This commit fixes the last issue exposed by #1074

fixes #1074
2022-03-25 19:13:21 -07:00
Leonardo de Moura
3a310fb122 fix: the eta for structures implementation in the elaborator was different from the implementation in the kernel
This issue was exposed by issue #1074
2022-03-25 18:24:15 -07:00
Leonardo de Moura
d4d5d3693e chore: update stage0 2022-03-25 18:18:03 -07:00
Leonardo de Moura
1900efd91a chore: add pp_expr helper function 2022-03-25 18:16:18 -07:00
Leonardo de Moura
7307b02fd7 fix: missing test at has_trivial_structure
see #1074
2022-03-25 17:36:30 -07:00
Sebastian Ullrich
2740cab3fc chore: update RELEASES 2022-03-26 00:02:13 +01:00
Leonardo de Moura
130bbfc501 chore: update README 2022-03-25 14:48:07 -07:00
Leonardo de Moura
9aca413e31 chore: add link to doc/examples 2022-03-25 14:46:43 -07:00
Leonardo de Moura
6da9119516 doc: add Parametric Higher-Order Abstract Syntax example 2022-03-25 14:42:24 -07:00
Sebastian Ullrich
ca9678be58 doc: move tier list to setup.md 2022-03-25 17:45:15 +01:00
Sebastian Ullrich
7ce4a85d25 doc: add platform support tiers to README 2022-03-25 17:45:15 +01:00
Sebastian Ullrich
7e853621eb feat: CI: build linux_aarch64 2022-03-25 17:45:15 +01:00
Leonardo de Moura
e53435979f fix: remove hacky addAutoBoundImplicitsOld 2022-03-25 09:23:43 -07:00
Leonardo de Moura
6631d92d7b fix: addAutoBoundImplicitsOld occurrences at MutualDef.lean and Structure.lean
This commit also fixes non-termination at `collectUnassignedMVars`
2022-03-25 09:07:59 -07:00
Leonardo de Moura
e48cc8901e fix: add new addAutoBoundImplicits that avoids the hack at addAutoBoundImplicitsOld 2022-03-25 08:40:57 -07:00
Leonardo de Moura
519b780164 doc: document InfoTree issue 2022-03-25 07:12:07 -07:00
Leonardo de Moura
370e9c421f fix: bug at deriving Hashable 2022-03-24 18:46:10 -07:00
E.W.Ayers
534aa88188 doc: MetaM 2022-03-24 16:57:42 -07:00
Leonardo de Moura
3c9556ec18 doc: finish deBruijn.lean example 2022-03-24 16:17:53 -07:00
Leonardo de Moura
52a52fbed7 chore: add doc/examples to the test suite 2022-03-24 15:20:18 -07:00
Arthur Paulino
53faa9c8ca doc: restriction of partial functions 2022-03-24 15:01:50 -07:00
E.W.Ayers
90baf14e82 doc: add lib and style changes to lean3changes.md 2022-03-24 15:00:36 -07:00
E.W.Ayers
1e69639fd2 doc: clarify mkLocalDecl 2022-03-24 14:59:46 -07:00
E.W.Ayers
6f5fc72c06 doc: Docstrings for LocalContext.lean 2022-03-24 14:59:46 -07:00
E.W.Ayers
24ebd78071 doc: Expr.lean 2022-03-24 14:52:09 -07:00
Wojciech Nawrocki
8f83c7ab32 feat: user-defined RPC handlers 2022-03-24 08:09:33 -07:00
Sebastian Ullrich
e49949b781 chore: prepare-llvm-linux: fix include path order
should really be `-isystem-after`, but clang ignores it...??
2022-03-24 12:33:33 +01:00
Sebastian Ullrich
75b3012a37 chore: prepare-llvm-linux: stop relying on /usr 2022-03-24 12:33:33 +01:00
Sebastian Ullrich
720e445755 chore: Nix: update inputs 2022-03-24 12:33:33 +01:00
Sebastian Ullrich
5c6e054e24 chore: update to LLVM 14 2022-03-24 12:33:33 +01:00
Leonardo de Moura
fdbe893c40 fix: catch mkAppM exceptions 2022-03-23 17:35:04 -07:00
Leonardo de Moura
96de208a6b chore: remove some partial 2022-03-23 17:16:30 -07:00
Sebastian Ullrich
8a5febf130 chore: CI: fix release job 2022-03-23 19:33:25 +01:00
Leonardo de Moura
be7c71d1c8 chore: update date 2022-03-23 07:44:15 -07:00
Leonardo de Moura
e0aa9fb290 chore: fix typo 2022-03-23 07:39:46 -07:00
Leonardo de Moura
170b911a6f doc: expand deBruijn 2022-03-22 19:35:58 -07:00
Leonardo de Moura
20fb3e470d doc: add dependent de Bruijn indices
TODO: explain example.
2022-03-22 19:11:06 -07:00
Leonardo de Moura
b2a1b88a4e doc: a certified type checker 2022-03-22 19:01:26 -07:00
Leonardo de Moura
a23fcb6033 chore: use github link until we generate the proper webpage using Alectryon 2022-03-22 18:34:40 -07:00
Leonardo de Moura
028e3561e2 fix: link 2022-03-22 18:07:04 -07:00
Leonardo de Moura
265803f7ac doc: fix links 2022-03-22 16:52:08 -07:00
Leonardo de Moura
e06893d1f2 doc: proper TPIL link 2022-03-22 16:37:16 -07:00
Leonardo de Moura
973b76a6e2 doc: add Examples section 2022-03-22 16:35:14 -07:00
Leonardo de Moura
412bc14fbe doc: add well-typed interpreter as an example 2022-03-22 16:32:41 -07:00
Leonardo de Moura
5ae125262b chore: remove C++ coding style from manual 2022-03-22 15:54:51 -07:00
Leonardo de Moura
2e9adf0e04 chore: remove broken documentation 2022-03-22 15:52:13 -07:00
Leonardo de Moura
9d32d7bcf5 test: for issue #1062
closes #1062
2022-03-22 14:14:28 -07:00
Leonardo de Moura
2f67140603 fix: incorrect uses of getMVarType' 2022-03-22 14:11:29 -07:00
Leonardo de Moura
6007147d71 fix: allow universes to be postponed further
closes #1058
2022-03-22 13:57:58 -07:00
Leonardo de Moura
f3b181b972 chore: comment withoutPostponingUniverseConstraints 2022-03-22 13:57:58 -07:00
Mario Carneiro
c29da66c5a fix: annotate binders in intro for hover / go to def 2022-03-22 12:10:51 +00:00
Sebastian Ullrich
3818ea8333 chore: CI: document previous workaround 2022-03-22 12:25:59 +01:00
Sebastian Ullrich
c758d442dc chore: CI: try using the correct C++ compiler for tests on Windows 2022-03-22 12:22:23 +01:00
Sebastian Ullrich
bba0baf92c chore: CI: I'm sure they work fine 2022-03-22 12:22:23 +01:00
Sebastian Ullrich
82049c519c chore: CI: fix MinGW library root 2022-03-22 12:22:23 +01:00
Sebastian Ullrich
00aeaed544 chore: CI: fix manual build 2022-03-22 09:36:52 +01:00
Sebastian Ullrich
c4d3c74837 feat: accept multiple patterns after matches 2022-03-21 17:59:02 +01:00
Sebastian Ullrich
cb93590f0b chore: update stage0 2022-03-21 17:47:03 +01:00
Sebastian Ullrich
faedfbe651 fix: antiquotation splices early in bootstrapping 2022-03-21 17:44:15 +01:00
Leonardo de Moura
3d9e587862 fix: check type mismatch at dependent pattern matching compiler
see issue #1057
2022-03-21 09:28:02 -07:00
Leonardo de Moura
9944feb095 test: use [reducible] 2022-03-21 07:39:44 -07:00
Sebastian Ullrich
89a3f6d623 chore: update Lake 2022-03-21 14:50:54 +01:00
Sebastian Ullrich
1a5822a3e2 chore: update Lake 2022-03-21 14:02:36 +01:00
Leonardo de Moura
3a75cf1920 test: nested inductives 2022-03-21 05:57:02 -07:00
Leonardo de Moura
cba204e3cb chore: update stage0 2022-03-20 18:47:28 -07:00
Leonardo de Moura
321d6b0e67 feat: support for user-defined simp attributes in the simp tactic.
See `RELEASES.md`

TODO: make sure `-thm` also removes `thm` from user-defined simp attributes.
2022-03-20 18:45:57 -07:00
Leonardo de Moura
a2690d5278 feat: improve #eval command 2022-03-20 15:18:47 -07:00
Leonardo de Moura
7b1091770c test: Repr for HList 2022-03-20 15:05:34 -07:00
Leonardo de Moura
6d926c7989 feat: macro expand match alternatives
see #371

This commit does not implement all features discussed in this issue.
It has implemented it as a macro expansion. Thus, the following is
accepted
```lean
inductive StrOrNum where
  | S (s : String)
  | I (i : Int)

def StrOrNum.asString (x : StrOrNum) :=
  match x with
  | I a | S a => toString a
```
It may confuse the Lean LSP server. The `a` on `toString` shows the
information for the first alternative after expansion (i.e., `a` is an `Int`).
After expansion, we have
```
def StrOrNum.asString (x : StrOrNum) :=
  match x with
  | I a => toString a
  | S a => toString a
```
2022-03-20 14:20:13 -07:00
Leonardo de Moura
51ee6fe4f1 chore: fix test 2022-03-20 13:27:19 -07:00
Leonardo de Moura
476bcee8ba chore: update stage0 2022-03-20 13:25:03 -07:00
Leonardo de Moura
8f4d58893f feat: update match parser
Support for
```
def fib (x : Nat) : Nat :=
  match x with
  | 0 | 1 => 1
  | x+2   => fib (x+1) + fib x
```

TODO: expand `matchAlts`
2022-03-20 13:22:39 -07:00
Leonardo de Moura
87bb299f08 feat: add Iterator.atEnd 2022-03-20 11:40:46 -07:00
Leonardo de Moura
4f9dcd55ce chore: update stage0 2022-03-20 10:59:21 -07:00
Leonardo de Moura
3862e7867b refactor: make String.Pos opaque
TODO: this refactoring exposed bugs in `FuzzyMatching` and `Lake`

closes #410
2022-03-20 10:47:13 -07:00
Jakob von Raumer
a91f92c11e feat: allow constants to be type classes
There no reason against constants to be type classes so it is just the check in `addClass` that is needed to be modified.

Closes #1054
2022-03-20 08:03:34 -07:00
Leonardo de Moura
6e94801c00 chore: update stage0 2022-03-19 16:55:26 -07:00
Leonardo de Moura
1b357db3b0 fix: nasty bug at findDeclarationRangesCore?
We must search the environment extension first, and then the builtin
table. Otherwise, the builtin declarations do not change when we
modify the files.

closes #1021
2022-03-19 16:53:22 -07:00
Leonardo de Moura
ed7c8904a9 fix: propagate local and scope modifiers at elab_rules
closes #1039
2022-03-19 16:08:06 -07:00
Leonardo de Moura
82cd5c8eef chore: cleanup 2022-03-19 15:52:04 -07:00
E.W.Ayers
da68f629f9 style: Apply.lean
Apply Leo's review requests.
2022-03-19 15:51:40 -07:00
E.W.Ayers
d954706fcf feat: ApplyNewGoals config for apply
Lean.Meta.Tactic.apply now accepts an ApplyConfig argument.
`apply` now changes which metavariables are stored with choice
of the newGoals config.
This allows one to implement `fapply` and `eapply`.
An example of this is given in tests/lean/run/apply_tac.lean.

Closes #1045
2022-03-19 15:51:40 -07:00
casavaca
bf4ba1583d feat: add simp theorem for List, (as.map f).length = as.length 2022-03-19 11:35:21 -07:00
Leonardo de Moura
72b6f4d528 chore: avoid unnecessary h :s 2022-03-19 11:21:37 -07:00
Leonardo de Moura
f29319647f chore: update stage0 2022-03-19 11:16:24 -07:00
Leonardo de Moura
4f318d3304 test: use dot notation in the example 2022-03-19 10:39:58 -07:00
Leonardo de Moura
d1eb180aae test: add non mutually recursive version 2022-03-19 10:38:39 -07:00
Leonardo de Moura
bdb2e9597a chore: naming convention 2022-03-19 10:20:42 -07:00
Leonardo de Moura
6c8322d20a test: use builtin Char.isDigit and Char.toNat 2022-03-19 10:18:34 -07:00
Leonardo de Moura
a8ddb56e0e chore: cleanup David's example 2022-03-19 10:13:27 -07:00
Leonardo de Moura
c95d5f25a3 feat: convert ites into dites in the WF module
Motivation: the condition is often used in termination proofs.
2022-03-19 10:11:50 -07:00
Leonardo de Moura
9fed5bda7d chore: remove workarounds 2022-03-19 09:44:57 -07:00
Leonardo de Moura
544421faf5 chore: update stage0 2022-03-19 09:43:57 -07:00
Leonardo de Moura
36d955e8cc feat: use simpler encoding for nonmutually recursive definitions 2022-03-19 09:43:18 -07:00
Leonardo de Moura
4b374d4441 fix: Nat/Div.lean, add decreasing_with combinator, and rename decreasing_tactic_trivial 2022-03-19 09:40:10 -07:00
Leonardo de Moura
5e3b3494e2 chore: update stage0 2022-03-19 09:30:34 -07:00
Leonardo de Moura
c7cdbf8ff8 feat: improve auto generated termination_by a bit 2022-03-19 09:28:19 -07:00
Leonardo de Moura
64c5cda612 test: David's lex with string iterators 2022-03-19 09:15:29 -07:00
Leonardo de Moura
9722aeaf32 feat: use String.Iterator.sizeOf_next_lt in the builtin decreasing_tactic 2022-03-19 09:04:40 -07:00
Leonardo de Moura
7dd38a7194 feat: add with_unfolding_all and rfl' tactics 2022-03-19 08:57:04 -07:00
Leonardo de Moura
63e42a8179 chore: fix copyright date
File was created in 2022.
2022-03-19 08:44:21 -07:00
Leonardo de Moura
c8c4d47420 feat: make decreasing_tactic easier to extend 2022-03-19 08:42:38 -07:00
Leonardo de Moura
ef3143e1eb chore: update stage0 2022-03-19 08:39:34 -07:00
Leonardo de Moura
fa74194638 fix: missing s.restore at expandTacticMacroFns 2022-03-19 08:34:54 -07:00
Leonardo de Moura
bd7827ed04 feat: dbg_trace tactic for low-level tactic debugging 2022-03-19 08:25:49 -07:00
Leonardo de Moura
9727387129 feat: helper theorem for proving termination of simple String traversal functions 2022-03-19 07:37:59 -07:00
Leonardo de Moura
ed3c792a4c chore: update stage0 2022-03-19 07:21:52 -07:00
Leonardo de Moura
64bd82dddd feat: custom SizeOf instance for String.Iterator 2022-03-19 07:21:17 -07:00
Leonardo de Moura
4ac88d0eb8 test: lex example from David 2022-03-18 19:53:17 -07:00
Leonardo de Moura
a486503c62 chore: fold Nat literals at reduce 2022-03-18 17:10:46 -07:00
Leonardo de Moura
1514e39006 chore: add double ticks 2022-03-18 17:10:46 -07:00
Leonardo de Moura
42b707e250 perf: improve getMatchWithExtra 2022-03-18 17:10:46 -07:00
Sebastian Ullrich
d5b3430e53 chore: ignore stage0/ (for rg etc.) 2022-03-18 15:28:20 +01:00
Leonardo de Moura
38a1675c72 fix: dicrimination tree getMatchWithExtra
It was buggy when the input argument could be reduced `e`.

fixes #1048
2022-03-17 16:44:38 -07:00
Leonardo de Moura
3193acecfa fix: flush the CoreM and MetaM caches at modifyEnv
This fix may impact performance. Note that we don't need to flush the
cache if we are "adding" stuff to the environment. We only need to
flush the caches if the change is not monotonic. BTW, most of the
changes are monotonic. I think this is why we did not hit this bug before.

We may also move all these caches to an environment extension. It is
an easy way to make sure we preserve the cache when extending the
environment.

I tried a few benchmarks and did not notice a significant difference.

cc @kha @gebner

fixes #1051
2022-03-17 16:02:30 -07:00
Leonardo de Moura
719db55a9c chore: fix trace class 2022-03-17 13:22:16 -07:00
Leonardo de Moura
184b0b8e8d feat: improve "result types must be in the same universe level" error message
The new error message makes it clear why the definition is not accepted.

See issue #1050
2022-03-17 07:41:37 -07:00
zygi
ac793ce196 fix: forward start and stop in Array.allM 2022-03-17 10:08:40 +01:00
Sebastian Ullrich
0d03c6e319 chore: revise non-GMP interface 2022-03-16 17:32:51 -07:00
Daniel Fabian
969eea19f0 refactor: do not use mkAppM so much 2022-03-16 17:21:20 -07:00
Daniel Fabian
cf4e873974 feat: support Sort u in ac_refl. 2022-03-16 17:21:20 -07:00
Daniel Fabian
8e0763f502 fix: binder case. 2022-03-16 17:21:20 -07:00
Daniel Fabian
d667d5ab5d feat: rewrite the tactic using simp as the basis. 2022-03-16 17:21:20 -07:00
Daniel Fabian
ed63274874 refactor: move ac_refl syntaxt to Init/Notation 2022-03-16 17:21:20 -07:00
Daniel Fabian
73a59e5bc4 feat: use simp instead of rewrite inside of ac_refl 2022-03-16 17:21:20 -07:00
Daniel Fabian
fda1c5b192 refactor: simplify proof using <;> 2022-03-16 17:21:20 -07:00
Daniel Fabian
84f72b9389 test: add further ac_refl tests. 2022-03-16 17:21:20 -07:00
Daniel Fabian
a60220b036 feat: add tactic for ac_refl. 2022-03-16 17:21:20 -07:00
Daniel Fabian
eaa48f0d8d refactor: move ac proofs to Init. 2022-03-16 17:21:20 -07:00
Daniel Fabian
1114dfac6c feat: add theory for ac normalization.
This lets us implement an AC reflexivity tactic.
2022-03-16 17:21:20 -07:00
Leonardo de Moura
4320a61f4d chore: use Prod notation in test 2022-03-16 17:14:16 -07:00
Leonardo de Moura
50813429b8 fix: add expected type hint
Other tactics (e.g., `simp_all`) may try to infer the type of the
proof, and `Nat.Linear.eq_of_toNormPoly_eq` has a messy resulting type.
2022-03-16 17:07:22 -07:00
Leonardo de Moura
cb925a3a3c fix: return some at simpCnstrPos? if arith expr was normalized, but not simplified
Example: converted `<`, `>`, or `>=` into `<=`.
2022-03-16 16:36:39 -07:00
Leonardo de Moura
9b9ed6db68 feat: add simp_all_arith macro 2022-03-16 16:17:45 -07:00
Leonardo de Moura
4ba5a9b041 fix: bug at KExprMap 2022-03-16 16:07:14 -07:00
Leonardo de Moura
09648521d1 chore: add Repr instances 2022-03-16 16:07:14 -07:00
Sebastian Ullrich
4fd520e902 feat: generalize inferred namespace notation to functions 2022-03-16 23:40:05 +01:00
Leonardo de Moura
68154a6c69 test: add Pos view 2022-03-16 10:08:43 -07:00
Leonardo de Moura
05a2778b0d fix: ensure explicit pattern variables provided by the uses are indeed pattern variables 2022-03-16 07:50:29 -07:00
Leonardo de Moura
90c442da76 feat: add internal option for communicating to the delaborator that input term is a pattern 2022-03-16 07:50:29 -07:00
Sebastian Ullrich
a3c73f5df8 chore: remove orphan file 2022-03-16 10:25:18 +01:00
Leonardo de Moura
0a2d0bc3fd chore: update stage0 2022-03-15 17:43:52 -07:00
Leonardo de Moura
0bd9de1cb9 perf: add InstantiateLevelCaches for types and values at CoreM 2022-03-15 17:42:38 -07:00
Leonardo de Moura
d6de53a7aa perf: custom splitAnd 2022-03-15 16:59:11 -07:00
Leonardo de Moura
b8a4f3a7a3 perf: quick filter for simpMatch when proving equation theorems 2022-03-15 15:53:29 -07:00
Leonardo de Moura
e44b36cab0 chore: cleanup optimization using Lean bitwise operators 2022-03-15 12:06:08 -07:00
Leonardo de Moura
49e33fdb23 chore: fix tests 2022-03-15 11:35:47 -07:00
Leonardo de Moura
e1ba83d902 chore: update stage0 2022-03-15 11:31:39 -07:00
Leonardo de Moura
d3e2dfb079 perf: optimize mkApp 2022-03-15 11:31:15 -07:00
Leonardo de Moura
9d73317d76 perf: faster Expr.data 2022-03-15 11:30:41 -07:00
Leonardo de Moura
d2dc38fdb6 perf: use HasConstCache to minimize the number of visited terms at Structural and WF
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2022-03-15 08:40:47 -07:00
Leonardo de Moura
5283007aa4 feat: add HasConstCache 2022-03-15 08:39:48 -07:00
Leonardo de Moura
3278d7bc2a chore: update stage0 2022-03-15 07:16:17 -07:00
Leonardo de Moura
ca6453a0ab perf: efficient unsigned hash(expr const & e) 2022-03-15 07:15:00 -07:00
Leonardo de Moura
eccd5c11c9 perf: removeUnusedEqnHypotheses 2022-03-15 06:53:43 -07:00
Leonardo de Moura
2b71bc84f3 perf: try injection before contradiction at mkSplitterProof 2022-03-15 05:37:10 -07:00
Leonardo de Moura
c3c0b8b8a2 chore: remove unnecessary code 2022-03-15 05:26:33 -07:00
Leonardo de Moura
aa68057c85 chore: more general type universes in example 2022-03-15 05:19:02 -07:00
Leonardo de Moura
7ee7ca30b8 fix: index out of bounds 2022-03-15 05:16:19 -07:00
Leonardo de Moura
4e261b15e5 fix: smart unfolding bug in over applications 2022-03-14 19:17:21 -07:00
Leonardo de Moura
eb7539ef77 fix: mkEqnTypes overapplied lhs in equational theorems
This issue was exposed by the "Dependent de Bruijn indices" from CPDT.
2022-03-14 17:42:21 -07:00
Leonardo de Moura
c6dae18787 chore: add helper theorems 2022-03-14 16:24:05 -07:00
Leonardo de Moura
40f608bfbd chore: cleanup String.extract reference implementation 2022-03-14 16:23:13 -07:00
Leonardo de Moura
8e29747fe7 feat: add simp theorem (a : Nat) : (a ≤ 0) = (a = 0) 2022-03-14 15:43:42 -07:00
Leonardo de Moura
bbe6bd4e72 chore: simplify String.utf8ByteSize reference implementation 2022-03-14 15:42:58 -07:00
Leonardo de Moura
14ed473777 feat: mark Nat.zero_le as simp theorem 2022-03-14 15:19:52 -07:00
Leonardo de Moura
7fda1f47f8 test: add test for issue fixed in previous commit 2022-03-14 14:11:08 -07:00
Leonardo de Moura
86fc089e07 fix: tryAutoCongrTheorem? may still use dsimp for fixed arguments
Reviewed-by: Leonardo de Moura <leonardo@microsoft.com>
2022-03-14 14:04:28 -07:00
Leonardo de Moura
ef154ec0cf test: add TreeNode example using for in notation 2022-03-14 11:52:54 -07:00
Leonardo de Moura
cab3217b05 feat: add forIn'_eq_forIn theorem for lists 2022-03-14 11:50:47 -07:00
Leonardo de Moura
2ac9cfb7b1 fix: eta expand partial applications of recursive function being defined 2022-03-14 10:05:33 -07:00
Leonardo de Moura
801552e1ac chore: fix tests 2022-03-14 10:05:33 -07:00
Leonardo de Moura
9988faf8bd fix: missing mkRecAppWithSyntax 2022-03-14 10:05:33 -07:00
Leonardo de Moura
02145f66cf chore: fix typo 2022-03-14 10:05:33 -07:00
Sebastian Ullrich
147a5c2933 chore: prefer LEAN_SRC_PATH 2022-03-14 17:24:25 +01:00
Leonardo de Moura
d2cc5b4a83 chore: fix test 2022-03-13 15:53:21 -07:00
Leonardo de Moura
fa0964c07e fix: preserve variable name at WF decreasing goals when function has only one non fixed argument 2022-03-13 13:20:07 -07:00
Leonardo de Moura
060be7e7ec fix: :: is infix right 2022-03-13 09:25:56 -07:00
Leonardo de Moura
672a889c83 test: add hlist pattern match example 2022-03-13 09:15:55 -07:00
Leonardo de Moura
30c153aa76 chore: update stage0 2022-03-12 20:18:20 -08:00
Leonardo de Moura
bfe57a1cb0 chore: simplify definition 2022-03-12 20:16:45 -08:00
Leonardo de Moura
231120c118 chore: update RELEASES.md 2022-03-12 20:02:39 -08:00
Leonardo de Moura
5707cab7bf feat: improve #eval command
Now, if it fails to synthesize the TC instance, it applies `whnf` and
tries again.
2022-03-12 19:55:15 -08:00
Leonardo de Moura
3cd41acd14 test: HList with notation overloads 2022-03-12 19:47:57 -08:00
Leonardo de Moura
af5a24140a test: simple type checker at CPDT 2022-03-12 18:44:52 -08:00
Leonardo de Moura
7e3519a3a2 test: add CPDT first example 2022-03-12 17:06:20 -08:00
Leonardo de Moura
f0c31d7e28 feat: allow rw to unfold nonrecursive definitions too 2022-03-12 15:44:52 -08:00
Leonardo de Moura
c0a72172f1 chore: update stage0 2022-03-12 15:35:09 -08:00
Leonardo de Moura
7af09ac009 refactor: move equation theorem cache to Meta/Eqns.lean 2022-03-12 15:34:32 -08:00
Leonardo de Moura
cf0ca026fb feat: equation theorems at rw 2022-03-12 13:53:02 -08:00
Leonardo de Moura
9d1dbada79 feat: only try to generate equation theorems for definitions whose types are not propositions 2022-03-12 13:44:33 -08:00
Leonardo de Moura
8a46668884 chore: update stage0 2022-03-12 10:46:17 -08:00
Leonardo de Moura
a6bfefe5bd fix: nasty performance problem at isDefEq
This problem was originally exposed by the `Array.eraseIdxAux`.
2022-03-12 10:44:43 -08:00
Leonardo de Moura
eddcedb58c fix: pattern normalization code 2022-03-12 06:07:04 -08:00
Lars
95cf18457d chore: address review comments 2022-03-12 13:25:35 +00:00
Sebastian Ullrich
82c682d385 chore: remove redundant proof 2022-03-12 11:12:56 +01:00
Leonardo de Moura
a4f47adf9e fix: normalize method at Match.lean 2022-03-11 18:19:37 -08:00
Leonardo de Moura
63dcf2124c chore: add link to quickstart to README 2022-03-11 16:35:07 -08:00
Chris Lovett
6dc576121d doc: replace quickstart leanpkg info with info about lake 2022-03-11 16:31:58 -08:00
Leonardo de Moura
15e30a93f3 feat: update RELEASES.md 2022-03-11 16:28:01 -08:00
larsk21
e430496903 doc: fix fuzzy matching docs 2022-03-11 16:25:26 -08:00
larsk21
ea5b6d568f fix: review suggestions + code structure 2022-03-11 16:25:26 -08:00
larsk21
0ef3ea4bc9 feat: enable fuzzy matching for workspace symbols 2022-03-11 16:25:26 -08:00
larsk21
64dba41b4c feat: enable fuzzy matching for completion 2022-03-11 16:25:26 -08:00
Sebastian Ullrich
ff11325fce perf: use mkArray in fuzzyMatchCore 2022-03-11 16:25:26 -08:00
Sebastian Ullrich
d48c5b99e9 perf: eliminate MProd allocations in iterateLookaround 2022-03-11 16:25:26 -08:00
Sebastian Ullrich
896b9b48a3 perf: eliminate some allocations in iterateLookaround 2022-03-11 16:25:26 -08:00
Sebastian Ullrich
7106d3fb34 perf: specialize iterateLookaround 2022-03-11 16:25:26 -08:00
larsk21
135eac71a1 feat: add string fuzzy matching 2022-03-11 16:25:26 -08:00
Leonardo de Moura
5caf1bc692 chore: style
Use `·` instead of `.` for structuring tactics.
2022-03-11 16:12:46 -08:00
Leonardo de Moura
ddf93d2f8a feat: support for arrow types in the dot notation
cc @gebner
2022-03-11 15:39:41 -08:00
Leonardo de Moura
8d42978e63 feat: generate error message when induction tactic is used on a nested inductive type without specifying an eliminator 2022-03-11 14:45:57 -08:00
Leonardo de Moura
712e9b7d45 chore: add custom induction principle for LazyList 2022-03-11 14:21:35 -08:00
Leonardo de Moura
7d5da95434 fix: remove unused hypotheses from conditional equation theorems 2022-03-11 14:10:57 -08:00
Leonardo de Moura
54b74796f6 feat: use tryContradiction at mkUnfoldProof 2022-03-11 12:52:15 -08:00
Leonardo de Moura
272dd5533f chore: style use · instead of . for lambda dot notation
We are considering removing `.` as an alternative for `·` in the
lambda dot notation (e.g., `(·+·)`).
Reasons:
- `.` is not a perfect replacement for `·` (e.g., `(·.insert ·)`)
- `.` is too overloaded: `(f.x)` and `(f .x)` and `(f . x)`. We want to keep the first two.
2022-03-11 07:49:03 -08:00
Leonardo de Moura
2364bc7b46 chore: add link to issue 2022-03-10 17:10:12 -08:00
Leonardo de Moura
002412e9d0 chore: missing code block annotation 2022-03-10 17:08:54 -08:00
Leonardo de Moura
1b5e9c7c83 chore: use new notation on its own implementation 2022-03-10 16:56:39 -08:00
Leonardo de Moura
61cd3dcc32 chore: update stage0 2022-03-10 16:55:40 -08:00
Leonardo de Moura
e1fa9c131c feat: inferring namespace from expected type a la Swift
Now that `PatternVars.lean` has been redesigned, it is feasible to
implement issue #944.

closes #944
2022-03-10 16:55:25 -08:00
Leonardo de Moura
7a7841fa95 chore: update stage0 2022-03-10 16:07:25 -08:00
Leonardo de Moura
1c99fe92ac feat: add dotIdent parser
see #944
2022-03-10 16:04:41 -08:00
Leonardo de Moura
3214a20d33 feat: allow overloaded notation in patterns 2022-03-10 12:51:34 -08:00
Leonardo de Moura
fddc8b06ac fix: missing case at getStuckMVar?
Fix issue reported at
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/'rewrite'.20failed.20but.20it.20should.20work/near/274870747
2022-03-10 10:33:11 -08:00
Leonardo de Moura
92318d07bb feat: add MonadBacktrack instance for CollectPatternVars.M monad 2022-03-10 10:23:18 -08:00
Leonardo de Moura
7a39be225d refactor: move methods to MetaM 2022-03-10 10:00:46 -08:00
Leonardo de Moura
2fb9a39cb4 refactor: implement MonadQuotation at CoreM 2022-03-10 09:55:20 -08:00
Leonardo de Moura
3edb0ede04 chore: update stage0 2022-03-10 08:56:06 -08:00
Leonardo de Moura
7850dc023b fix: make sure the structure instance notation does not leak auxiliary type annotations (e.g., autoParam and optParam) 2022-03-10 08:41:00 -08:00
Leonardo de Moura
c1b1a916eb doc: update release notes 2022-03-10 08:26:27 -08:00
Leonardo de Moura
efc89eb4e1 fix: make sure inferProjType consume auxiliary type annotations 2022-03-10 08:15:34 -08:00
Leonardo de Moura
0ef8aaeda0 feat: make sure minor premises in recursors do not include auxiliary type annotations (e.g., autoParam and optParam) 2022-03-10 08:08:36 -08:00
Leonardo de Moura
1afee372f7 refactor: move consume_type_annotations declaration to expr.h 2022-03-10 08:00:39 -08:00
Leonardo de Moura
33883e9d2a fix: resulting type of projection functions should not include auxiliary type annotations (e.g., autoParam) 2022-03-10 07:47:38 -08:00
Leonardo de Moura
5825eb394f refactor: move isOutParam to Expr.lean, rename consumeAutoOptParam => consumeTypeAnnotations 2022-03-10 07:37:41 -08:00
Leonardo de Moura
38668308ef fix: do not rename metavariables that are already in the patternVars array
It fixes a regression introduced yesterday.
2022-03-10 05:53:54 -08:00
Leonardo de Moura
9c5f6361a3 doc: document the new pattern elaboration procedure 2022-03-09 18:58:23 -08:00
Leonardo de Moura
ca253c43e1 refactor: pattern elaboration
We don't use the following hack anymore:
-  /- HACK: `fvarId` is not in the scope of `mvarId`
-     If this generates problems in the future, we should update the metavariable declarations. -/
-  assignExprMVar mvarId (mkFVar fvarId)

This hack was corrupting the `InfoTree`.
2022-03-09 18:19:14 -08:00
Leonardo de Moura
b0246172fa chore: add comment and remove dbg trace message 2022-03-09 14:02:30 -08:00
Leonardo de Moura
b6dc3dda04 chore: fix tests 2022-03-09 14:02:13 -08:00
Leonardo de Moura
caa1366b62 fea: erase nested inaccessible annotations 2022-03-09 14:01:59 -08:00
Leonardo de Moura
1609f96128 refactor: simplify PatternVar.lean and Match.lean 2022-03-09 14:01:40 -08:00
Leonardo de Moura
74411aa472 fix: do not display implicit fields 2022-03-09 12:33:22 -08:00
Leonardo de Moura
50ae170bcc feat: allow mkLambdaFVars and mkForallFVars to abstract unassigned metavars too 2022-03-09 11:27:58 -08:00
Leonardo de Moura
4660485ac8 refactor: collectDeps => collectForwardDeps 2022-03-09 11:27:58 -08:00
Leonardo de Moura
5636c94cd0 chore: remove old comment, simplify exception 2022-03-09 11:27:58 -08:00
Leonardo de Moura
1263cea6af feat: add support for unassigned metavariables at dependsOn 2022-03-09 11:27:58 -08:00
Sebastian Ullrich
db9b963af7 chore: Nix: adjust message 2022-03-09 10:31:32 +01:00
Sebastian Ullrich
202258cc87 chore: Nix: remove debug flag 2022-03-09 10:30:37 +01:00
Sebastian Ullrich
a7438e9eae chore: Nix: remove debug flag 2022-03-09 10:30:09 +01:00
Sebastian Ullrich
7821a201e9 chore: Nix: update Nix 2022-03-09 10:29:25 +01:00
Sebastian Ullrich
126c7dd4ea chore: Nix: command for (one-time) linking .ileans 2022-03-09 10:29:25 +01:00
Sebastian Ullrich
2221cc8141 chore: Nix: emulate lake serve 2022-03-09 10:14:43 +01:00
Leonardo de Moura
164f07a5e5 feat: generalize Expr.abstractRange
It now takes free variables **and** metavariables.
This is the first step to make `mkForallFVars` and `mkLambdaFVars`
more general.
2022-03-08 18:19:17 -08:00
Leonardo de Moura
d6b782f811 chore: remove workaround
for regression introduced by the following change

* Auto implicit behavior changed for inductive families. An auto implicit argument occurring in inductive family index is also treated as an index (IF it is not fixed, see next item)
2022-03-08 17:58:20 -08:00
Leonardo de Moura
3b7ada0b35 chore: update stage0 2022-03-08 17:58:20 -08:00
Leonardo de Moura
4ee131981d feat: in an inductive family the longest fixed prefix of indices is now promoted to parameters
This modification is relevant for fixing regressions on recent changes
to the auto implicit behavior for inductive families.

The following declarations are now accepted:
```lean
inductive HasType : Fin n → Vector Ty n → Ty → Type where
  | stop : HasType 0 (ty :: ctx) ty
  | pop  : HasType k ctx ty → HasType k.succ (u :: ctx) ty

inductive Sublist : List α → List α → Prop
  | slnil : Sublist [] []
  | cons l₁ l₂ a : Sublist l₁ l₂ → Sublist l₁ (a :: l₂)
  | cons2 l₁ l₂ a : Sublist l₁ l₂ → Sublist (a :: l₁) (a :: l₂)

inductive Lst : Type u → Type u
  | nil  : Lst α
  | cons : α → Lst α → Lst α
```

TODO: universe inference for `inductive` should be improved. The
current approach is not good enough when we have auto implicits.

TODO: allow implicit fixed indices that do not depend on indices that
cannot be moved to become parameters.
2022-03-08 17:56:34 -08:00
Leonardo de Moura
234046521a feat: print number of parameters for an inductive type 2022-03-08 17:48:46 -08:00
Leonardo de Moura
7b84b4cdaa fix: improve inductive indices elaboration
TODO: convert fixed indices to parameters. Motivation: types such as
```lean
inductive Foo : List α → Type
  | mk : Foo []
```
Users should not need to write
```lean
inductive Foo {α} : List α → Type
  | mk : Foo []
```
2022-03-08 17:48:46 -08:00
Leonardo de Moura
f74513384e refactor: cleanup addAutoBoundImplicits 2022-03-08 17:48:46 -08:00
Sebastian Ullrich
e9b8e54dcc feat: scientific parser alias for scientificLit 2022-03-08 18:54:05 +01:00
Sebastian Ullrich
dca5da6b18 chore: update RELEASES.md 2022-03-07 17:28:51 +01:00
Jonathan Coates
11cce61e4d chore: Clean up LSP folding a little
- Wait for all terms to be elaborated before showing folding regions.
   May want to change this to support partial results.
 - Use .span to extract import statements, rather than mutually
   recursive functions.
 - Some tiny other bits of cleanup
2022-03-07 17:23:35 +01:00
Jonathan Coates
04e60cebd1 feat: LSP code folding support
The following constructs are foldable:
 - Sections and namespaces
 - Blocks of import/open statements
 - Multi-line commands (so mostly definitions)
 - Mutual definitions
 - Module-level doc comments
 - Top-level definition doc comments

Fixes #1012
2022-03-07 17:23:35 +01:00
Sebastian Ullrich
dc8367d1f5 chore: CI: adjust nightly release time 2022-03-07 15:39:58 +01:00
Sebastian Ullrich
f2d5470f19 feat: allow interpretation of constants initialized by native code 2022-03-07 10:59:49 +01:00
Sebastian Ullrich
ff097e952f chore: link orphan file 2022-03-07 10:59:49 +01:00
Leonardo de Moura
dddfb65660 test: use notation 2022-03-06 19:28:01 -08:00
Leonardo de Moura
7c5604996a test: unfoldr 2022-03-06 19:26:04 -08:00
Leonardo de Moura
619186b2a8 feat: only use set_option codegen false where needed 2022-03-06 19:15:05 -08:00
Leonardo de Moura
10bccfe501 test: remove workaround 2022-03-06 13:58:42 -08:00
Leonardo de Moura
46d1111d3d fix: typo at unfoldBothDefEq 2022-03-06 13:54:42 -08:00
Leonardo de Moura
ff0f3bfc61 fix: interaction between overloaded notation and delayed coercions
The new test exposes this issue.
2022-03-06 09:49:15 -08:00
Leonardo de Moura
e9909020e8 test: add delay helper contructor 2022-03-06 08:08:51 -08:00
Leonardo de Moura
ad4b1796a0 chore: update stage0 2022-03-06 08:01:23 -08:00
Leonardo de Moura
b664a93d8e fix: a match application is stuck if one of the discriminants contain metavariables 2022-03-06 07:51:09 -08:00
Leonardo de Moura
8bcaafb28b fix: universe metavariables should not be taken into account at getKeyArgs 2022-03-06 07:50:19 -08:00
Leonardo de Moura
b105c006a5 fix: PrefixTree WellFormed type
`β` is a parameter.
2022-03-06 07:30:34 -08:00
Leonardo de Moura
1450a86c4d feat: include types in the "ambiguous, possible interpretations" error message 2022-03-06 07:26:31 -08:00
Leonardo de Moura
d9a6680536 doc: describe the auto implicit chaining in the release notes 2022-03-05 17:45:56 -08:00
Leonardo de Moura
d3b2028a05 feat: add Fin.succ 2022-03-05 17:36:38 -08:00
Leonardo de Moura
3f9c854194 feat: auto local implicit chaining 2022-03-05 17:30:15 -08:00
Leonardo de Moura
f7130d8e07 refactor: use CPS at addAutoBoundImplicits
We want to be able to declare new local variables there.
2022-03-05 16:24:33 -08:00
Leonardo de Moura
22731c02b0 fix: auto implicit locals in inductive families 2022-03-05 15:47:20 -08:00
Leonardo de Moura
613cf19509 fix: discrimination trees and "stuck" terms
See comments and new test.
2022-03-05 15:12:20 -08:00
Leonardo de Moura
d39102f865 fix: smart unfolding for reducible definitions
When `TransparencyMode.reducible`, smart unfolding for reducible
definitions was not being used.
2022-03-05 14:42:47 -08:00
Leonardo de Moura
9e76cd7d65 fix: toName function at elabAppFnId
closes #1038
2022-03-04 16:56:02 -08:00
Leonardo de Moura
a670ed1e2d fix: use withoutErrToSorry at apply
closes #1037
2022-03-04 14:36:10 -08:00
Leonardo de Moura
a2457110db chore: update RELEASES.md 2022-03-03 20:05:58 -08:00
Leonardo de Moura
82b056aa75 chore: fix test 2022-03-03 19:53:35 -08:00
Leonardo de Moura
8b248e2d8c feat: elaborate for h : x in xs do ... notation 2022-03-03 19:52:26 -08:00
Leonardo de Moura
ef38c82c77 fix: missing hypotheses at List.sizeOf_lt_of_mem 2022-03-03 19:52:05 -08:00
Leonardo de Moura
99677823c3 fix: ForIn' instance binder annotations 2022-03-03 19:51:45 -08:00
Leonardo de Moura
b4ddcd600b chore: fix test 2022-03-03 19:15:07 -08:00
Leonardo de Moura
538eee0b6a chore: update stage0 2022-03-03 19:11:27 -08:00
Leonardo de Moura
5d2420b1c9 chore: add auxiliary notation for ForIn' 2022-03-03 19:10:24 -08:00
Leonardo de Moura
d8ee03c1bb feat: add ForIn' instance that is similar to ForIn but provides a proof that the iterated elements are in the collection 2022-03-03 19:05:27 -08:00
Leonardo de Moura
7462e3ad52 chore: update stage0 2022-03-03 18:29:04 -08:00
Leonardo de Moura
92937b3aba feat: add for h : x in xs do ... notation
The idea is to have `h : x \in xs`.
This commit just adds the parser.
2022-03-03 18:27:40 -08:00
Leonardo de Moura
51ec4522fe fix: documentation 2022-03-03 18:18:37 -08:00
Leonardo de Moura
e1424653b9 chore: remove workaround 2022-03-03 18:16:54 -08:00
Leonardo de Moura
0847c59667 chore: update stage0 2022-03-03 18:13:34 -08:00
Leonardo de Moura
b745c4f51a fix: recursive overapplication at WF/Fix.lean 2022-03-03 18:13:34 -08:00
Leonardo de Moura
f306c9b69b fix: split tactic
`unreachable!` assertions at `simpIfLocalDecl` and
`simpTargetLocalDecl` were reachable.
2022-03-03 18:13:34 -08:00
Leonardo de Moura
f4e98be163 fix: use whnfD at mkNoConfusion
The `split` tactic failed at `Array.sizeOf_lt_of_mem` because the type
in the equality is `Id Bool` when we write `true` instead of `id true`.
2022-03-03 18:13:34 -08:00
Leonardo de Moura
337c55f322 fix: missing import 2022-03-03 18:13:34 -08:00
Leonardo de Moura
4657d47c16 chore: fix tests 2022-03-03 18:13:34 -08:00
Leonardo de Moura
aeb9b2fb8c chore: add Membership instance for Array 2022-03-03 18:13:34 -08:00
Leonardo de Moura
fd519401ff feat: add Membership instance for List
and the theorem `a ∈ as -> sizeOf a < sizeOf as`.
We will use theorems like this one to improve the `decreasing_tactic`.
2022-03-03 18:13:21 -08:00
Leonardo de Moura
022a4d5ac1 feat: add notation 2022-03-03 17:18:51 -08:00
Leonardo de Moura
f629be745b chore: add Nat.le_refl as simp theorem 2022-03-03 17:18:11 -08:00
Leonardo de Moura
89c3820781 chore: naming convention 2022-03-03 17:17:51 -08:00
Leonardo de Moura
5845002e8c feat: use WF at anyM 2022-03-03 16:43:05 -08:00
Leonardo de Moura
3fa001911b feat: add ite_self simp theorem 2022-03-03 11:55:05 -08:00
Leonardo de Moura
e4fa3e5d83 chore: add link to RELEASES.md 2022-03-03 11:31:24 -08:00
Leonardo de Moura
30409fc73d chore: add example to RELEASES.md 2022-03-03 11:28:37 -08:00
Leonardo de Moura
02d7cedba8 chore: remove unnecessary termination_by annotations 2022-03-03 11:24:06 -08:00
Leonardo de Moura
35c587afbf chore: update stage0 2022-03-03 11:17:35 -08:00
Leonardo de Moura
137c70f055 chore: add LinearArith/Nat/Solver.lean 2022-03-03 11:13:40 -08:00
Leonardo de Moura
043d338271 feat: add getForbiddenByTrivialSizeOf 2022-03-03 11:12:32 -08:00
Leonardo de Moura
1f2618adba feat: delaborate cond using bif-then-else 2022-03-03 07:41:39 -08:00
Leonardo de Moura
8dd76868ff test: plan for supporting combinators (e.g., List.foldl) in WF recursion 2022-03-02 15:18:25 -08:00
Leonardo de Moura
e091e7fb30 test: simplify proofs 2022-03-02 13:57:43 -08:00
Leonardo de Moura
4ba97c22ec test: proving properties of mutually defined functions 2022-03-02 13:40:19 -08:00
Leonardo de Moura
1155d52702 chore: update TODO comment 2022-03-02 12:51:46 -08:00
Leonardo de Moura
14ef4b4304 test: add WF test that exposes the need for better error messages 2022-03-02 12:47:19 -08:00
Leonardo de Moura
093ab49b7f feat: improve generateElements a bit 2022-03-02 11:58:47 -08:00
Leonardo de Moura
52403fca83 feat: add support for guessing (very) simple WF relations
There are a lot of TODOs, but it is already useful for simple cases.

closes #847
2022-03-02 11:52:00 -08:00
Leonardo de Moura
99204d2226 refactor: modify elabWFRel to CPS 2022-03-02 11:52:00 -08:00
Leonardo de Moura
88a2645a5f refactor: add Lean/Meta/Tactic/LinearArith/Basic.lean 2022-03-02 11:52:00 -08:00
Leonardo de Moura
f171286e74 refactor: add src/Lean/Meta/Tactic/LinearArith/Nat 2022-03-02 11:52:00 -08:00
Sebastian Ullrich
c9713b1b69 fix: setExpectedFn 2022-03-02 16:28:53 +01:00
Leonardo de Moura
7eba003f53 chore: style 2022-03-01 18:54:10 -08:00
Leonardo de Moura
ca5696330c doc: update RELEASES.md 2022-03-01 18:51:15 -08:00
Leonardo de Moura
1e205d635e fix: bug at wfRecursion
"After compilation" attributes were being applied to soon when we did
not need to generate auxiliary functions.
2022-03-01 17:48:06 -08:00
Leonardo de Moura
bb2de82cb6 chore: update stage0 2022-03-01 17:47:40 -08:00
Leonardo de Moura
2daf8d62ac test: LazyList with Thunk 2022-03-01 16:55:56 -08:00
Leonardo de Moura
eac5bab429 chore: helper theorem 2022-03-01 16:54:25 -08:00
Leonardo de Moura
5dba98327c chore: update stage0 2022-03-01 16:41:28 -08:00
Leonardo de Moura
140559c447 feat: sizeOf for Thunks and Unit -> a 2022-03-01 16:40:11 -08:00
Leonardo de Moura
de51160929 fix: core library 2022-03-01 13:36:24 -08:00
François G. Dorais
e84699f130 fix: remove unnecessary hypotheses 2022-03-01 13:31:01 -08:00
Leonardo de Moura
e85abb6292 chore: update stage0 2022-03-01 13:25:54 -08:00
Leonardo de Moura
89e0de9fbb chore: use WF compiler to define Nat.mod and Nat.div 2022-03-01 13:08:59 -08:00
Leonardo de Moura
f16d8acb29 feat: eager normalization for proofs by reflection 2022-03-01 12:43:55 -08:00
Leonardo de Moura
0f796ac804 chore: avoid heterogeneous polymorphic operations and add add hugeFuel at Linear.lean 2022-03-01 11:25:15 -08:00
Leonardo de Moura
9bd82b798a chore: use bif instead of if at Linear.lean 2022-03-01 10:55:03 -08:00
Leonardo de Moura
0158c2eeb7 chore: update stage0 2022-03-01 09:03:20 -08:00
Leonardo de Moura
da55789c26 feat: add a proper BEq instance for Nat 2022-03-01 09:01:08 -08:00
Leonardo de Moura
85a1a5233b chore: workaround for compiler closed term extraction issue 2022-03-01 09:01:08 -08:00
Leonardo de Moura
5948003601 feat: add support for constant folding Nat.beq, Nat.blt, and Nat.ble 2022-03-01 09:01:08 -08:00
Gabriel Ebner
a7c9d2735f fix: do not apply eta for structures in Prop
The eta-expansion contains invalid projections, and the eta-rule is
subsumed by proof irrelevance anyhow.
2022-03-01 09:00:46 -08:00
Gabriel Ebner
3746005f5f fix: reject projection (_ : ∃ x, p).2
The inferred type of this projection does not even type check, in general.
2022-03-01 09:00:46 -08:00
Leonardo de Moura
0f06fbf648 feat: LawfulBEq must be reflexive 2022-02-28 19:27:51 -08:00
Leonardo de Moura
ecca71f0f5 chore: update stage0 2022-02-28 18:39:24 -08:00
Leonardo de Moura
7a49f71328 feat: add bif notation for cond function 2022-02-28 18:34:59 -08:00
Leonardo de Moura
4e310ac63d feat: improve SimpTheorem preprocessor 2022-02-28 18:27:36 -08:00
Leonardo de Moura
e8fb0c96ac feat: add helper theorems 2022-02-28 18:06:02 -08:00
Leonardo de Moura
5ddb3c3435 feat: faster PolyCnstr.combine 2022-02-28 17:24:26 -08:00
Leonardo de Moura
adf3510e08 chore: increase maxHeartbeats default values
We now increase the number of heartbeats at `expr_eq_fn`. Thus, the
old default values are too small.
2022-02-28 15:44:08 -08:00
Leonardo de Moura
b5f28239af feat: add List helper theorems 2022-02-28 15:16:13 -08:00
Leonardo de Moura
998a3de747 chore: update stage0 2022-02-28 15:13:38 -08:00
Leonardo de Moura
3005bab970 feat: helper theorem and tactic for WF 2022-02-28 15:11:00 -08:00
Leonardo de Moura
55bc048656 feat: make sure inequalities are normalized when no monomial was cancelled 2022-02-28 15:10:39 -08:00
Leonardo de Moura
e455df9c95 fix: use a def-eq aware mapping at toLinearExpr
The new test exposes the problem fixed by this commit.
In the termination proof we have two `sizeOf xs` terms that are not
syntactically identical (only definitional equal) because the
instances are different.
2022-02-28 13:46:36 -08:00
Leonardo de Moura
802922ddaf feat: add helper sizeOf simp theorems 2022-02-28 12:28:37 -08:00
Leonardo de Moura
2ba3205f94 feat: add Prod.Lex.right' 2022-02-28 11:19:28 -08:00
Leonardo de Moura
10657f5e81 feat: add trace <string> tactic 2022-02-28 11:16:42 -08:00
Leonardo de Moura
63a5cd5056 fix: trace_state messages should not be lost during backtracking 2022-02-28 11:07:41 -08:00
Leonardo de Moura
d89fa9d4c3 fix: endPos missing at trace messages 2022-02-28 10:55:45 -08:00
Leonardo de Moura
b7d2239ca4 chore: update stage0 2022-02-28 08:32:24 -08:00
Leonardo de Moura
46b97c2b70 fix: ExceptT.run_lift 2022-02-28 07:25:00 -08:00
Sebastian Ullrich
53d313c74c chore: fix function name 2022-02-28 16:16:22 +01:00
Leonardo de Moura
c5fdd54cd8 feat: support for acyclicity at unifyEqs
closes #1022
2022-02-27 10:03:40 -08:00
Leonardo de Moura
89f88b1caa feat: simplify nested arith expressions 2022-02-27 09:01:52 -08:00
Leonardo de Moura
c5baf759e2 fix: we must use addAsAxiom before getFixedPrefix
`getFixedPrefix` uses `isDefEq`, and it will fail if it needs to
retrieve the type of one of the recursive function being defined.
2022-02-27 09:01:52 -08:00
Leonardo de Moura
2c00823da9 test: simp_arith 2022-02-27 09:01:52 -08:00
Sebastian Ullrich
6c6f66b812 feat: propagate actual file name in file worker
Also stop recreating the FileMap for every command, that's quadratic!
2022-02-27 10:33:27 +01:00
Leonardo de Moura
90055fb7d4 chore: clarify error message at decreasing_tactic 2022-02-26 10:15:05 -08:00
Leonardo de Moura
f22b48b226 fix: display all remaining goals at fail tactic error message 2022-02-26 09:49:06 -08:00
Leonardo de Moura
f7f886dcb2 feat: improve error message for decreasing_tactic failures 2022-02-26 09:42:59 -08:00
Leonardo de Moura
cabd599de1 feat: add fail tactic 2022-02-26 09:31:19 -08:00
Leonardo de Moura
0242eb7ede feat: use simp (config := { arith := true }) at decreasing_tactic
closes #262
2022-02-26 09:12:34 -08:00
Leonardo de Moura
ff76958959 feat: basic support for linear Nat arithmetic at simp 2022-02-26 08:58:32 -08:00
Leonardo de Moura
41a5c2bce4 feat: add support for negation at simpCnstr? 2022-02-25 18:30:09 -08:00
Leonardo de Moura
5030e613a2 feat: add isSimpCnstrTarget 2022-02-25 17:18:50 -08:00
Leonardo de Moura
7217ee7754 fix: GE.ge and GT.gt support at simpCnstr? 2022-02-25 17:12:27 -08:00
Leonardo de Moura
812cc72285 chore: add helper theorems 2022-02-25 17:04:04 -08:00
Leonardo de Moura
0681d818ec chore: add helper function for simp 2022-02-25 16:42:41 -08:00
Leonardo de Moura
38da48c5cf refactor: LinearArith/Basic.lean => LinearArith/Solver.lean 2022-02-25 16:35:36 -08:00
Leonardo de Moura
cd710e903e chore: update stage0 2022-02-25 16:32:03 -08:00
Leonardo de Moura
77dda12bc9 chore: add Simp.Config.arith option 2022-02-25 16:30:44 -08:00
Leonardo de Moura
3f636b9f83 feat: add Lean.Meta.Linear.Nat.simpCnstr? 2022-02-25 16:27:21 -08:00
Leonardo de Moura
f7fd706973 chore: missing import 2022-02-25 16:20:26 -08:00
Leonardo de Moura
346930af9d feat: add ExprCnstr.eq_of_toNormPoly_eq 2022-02-25 14:55:20 -08:00
Leonardo de Moura
b8bed6fb5c feat: add LawfulBEq class 2022-02-25 13:35:08 -08:00
Leonardo de Moura
3b130ee42f feat: add Poly.toExpr 2022-02-25 12:31:30 -08:00
Leonardo de Moura
7d8cb84834 chore: update stage0 2022-02-25 08:50:05 -08:00
Leonardo de Moura
049273afee fix: add workarounds to code generator
The issue is only going to be properly fixed when we rewrite `csimp`
in Lean. The `csimp` performs transformations that do not preserve
typability, but it also uses the kernel `infer_type` which assumes the
input is type correct. In the new `csimp`, we must have a different
`infer_type` which returns an `Any` type in this kind of situation.

The workaround in this commit simply disables optimizations when
`infer_type` fails. It does not fix all occurrences of this problem,
but the two places that issue #1030 triggered.

closes #1030
2022-02-25 08:47:56 -08:00
Leonardo de Moura
4f7067fe7f fix: substEqs may close input goal
closes #1029
2022-02-25 08:07:23 -08:00
Leonardo de Moura
82e3789604 fix: run_lift type 2022-02-25 07:49:34 -08:00
Leonardo de Moura
7920db9521 feat: check for invalid projections during elaboration
It produces a better error message than the one produced by the
kernel.
2022-02-25 07:43:37 -08:00
Leonardo de Moura
04b93fc725 chore: fix invalid proof 2022-02-25 07:24:02 -08:00
Leonardo de Moura
0611eb84cc chore: update stage0 2022-02-25 07:22:59 -08:00
Leonardo de Moura
c9471ea029 fix: invalid proof 2022-02-25 07:17:31 -08:00
Leonardo de Moura
db38bc4043 fix: missing check at infer_proj
We should not allow `h.1` if `h` is a proposition and the result is
not. The recursor for `h`'s type can only eliminate into `Prop`.
2022-02-25 07:15:34 -08:00
Leonardo de Moura
622995b2c7 chore: style 2022-02-24 17:57:21 -08:00
Leonardo de Moura
e04ad112b2 fix: store levelNames in the SavedContext 2022-02-24 17:47:26 -08:00
Leonardo de Moura
be2e2cb70e chore: adjust proofs affected by update stage0 2022-02-24 17:20:17 -08:00
Leonardo de Moura
7480670c6a chore: update stage0 2022-02-24 17:18:42 -08:00
Leonardo de Moura
2961e9cbf0 fix: heuristic for deciding which additional propositions must be included in equality theorems 2022-02-24 17:17:07 -08:00
Leonardo de Moura
bdea43a52a feat: while and repeat macros 2022-02-24 16:26:07 -08:00
Leonardo de Moura
f7f04483b1 feat: add src/Lean/Meta/Tactic/LinearArith/Nat.lean 2022-02-24 15:24:59 -08:00
Leonardo de Moura
bd3ad35a1c fix: we may get False in unreachable branches 2022-02-24 15:24:07 -08:00
Leonardo de Moura
8131aa5a64 chore: add simp theorem heq_eq_eq 2022-02-24 13:45:34 -08:00
Leonardo de Moura
b134b9a3a4 chore: move isNatProjInst 2022-02-24 13:45:34 -08:00
Leonardo de Moura
a430b2ad71 chore: add copyright 2022-02-24 13:45:34 -08:00
Leonardo de Moura
05be43455a feat: add src/Init/Data/Nat/Linear.lean 2022-02-24 13:45:17 -08:00
Leonardo de Moura
43c2169f78 fix: when performing contextual simplification, and arrow may become a dependent arrow
fixes #1024
2022-02-23 18:43:32 -08:00
Leonardo de Moura
49c64040a2 feat: add support for HEq at injections tactic 2022-02-23 17:31:17 -08:00
Leonardo de Moura
07d1ec1926 fix: simp_all was "self-simplifying" simplified hypotheses
fixes #1027
2022-02-23 16:48:28 -08:00
Leonardo de Moura
16b8800607 chore: fix tests 2022-02-23 16:30:27 -08:00
Leonardo de Moura
0125db40a2 fix: remove [..] annotation from if simp theorems
fixes #1025
2022-02-23 16:28:12 -08:00
Leonardo de Moura
3e0ea7fbae fix: use instantiateMVars before invoking pure function findIfToSplit 2022-02-23 16:25:33 -08:00
Leonardo de Moura
a1366fcb3b chore: cleanup 2022-02-23 16:24:42 -08:00
Leonardo de Moura
c491659970 feat: improve split tactic error message 2022-02-23 16:00:42 -08:00
Leonardo de Moura
902e60c480 feat: add Format.isEmpty 2022-02-23 13:34:25 -08:00
Leonardo de Moura
52b53ab7a2 fix: heuristic for generating equation theorem types
closes #1026
2022-02-23 13:10:30 -08:00
Leonardo de Moura
2340f1b9bd feat: add isBRecOnRecursor 2022-02-23 13:09:29 -08:00
Leonardo de Moura
15546fbc48 feat: add Expr.findExt? 2022-02-23 12:32:17 -08:00
Leonardo de Moura
1ac9c1263b test: add helper theorems 2022-02-23 11:52:03 -08:00
Leonardo de Moura
dbe9bf61c5 fix: unfold auxiliary theorems created by decreasing_tactic 2022-02-23 09:02:23 -08:00
Leonardo de Moura
4794b9709f feat: improve equation theorem and match-splitter generation at MatchEqns.lean 2022-02-22 17:43:42 -08:00
Leonardo de Moura
52ff840321 feat: support for HEq at injection 2022-02-22 17:24:11 -08:00
Leonardo de Moura
c9f8ec71df fix: invalid rewrite when proving equation theorems for declaration using well-founded recursion 2022-02-22 16:38:51 -08:00
Leonardo de Moura
d36027d2fa test: add Certificate.of_combine_isUnsat 2022-02-22 16:04:23 -08:00
Leonardo de Moura
24249fecd3 feat: helper simp theorems 2022-02-22 16:03:36 -08:00
Leonardo de Moura
8d6750469e chore: helper Nat theorems 2022-02-22 14:26:50 -08:00
Leonardo de Moura
77fc0d3223 test: cleanup 2022-02-22 07:23:07 -08:00
Leonardo de Moura
c932d9d33c test: combine two inequalities 2022-02-21 15:13:37 -08:00
Leonardo de Moura
c73d177c94 perf: simpH? at MatchEqns.lean 2022-02-21 12:04:03 -08:00
Leonardo de Moura
0e40c63292 chore: fix typo 2022-02-21 10:55:38 -08:00
Leonardo de Moura
e9ee8ee86f test: add cancelation theorems for <= and < 2022-02-21 08:49:50 -08:00
Leonardo de Moura
7f3a3138d0 feat: helper Nat theorems 2022-02-21 08:49:50 -08:00
Sebastian Ullrich
d39c23f061 feat: quot precheck for 2022-02-21 10:14:39 +01:00
Leonardo de Moura
0986696758 test: add cancelation example 2022-02-20 17:35:33 -08:00
Leonardo de Moura
a8427702e8 test: reverse direction for cancelation procedure 2022-02-20 17:03:11 -08:00
Leonardo de Moura
33b1d2fd98 fix: preserve arrow binder names and info at simp
We use the idiom `revert; simp; ...; intro` in a few places. Some of
the reverted hypotheses manifest themselves as arrows in the target.
Before this commit, `simp` would lose the binder names and info when
simplifying an arrow, and we would get inaccessible names when
reintroducing them.
2022-02-20 16:27:40 -08:00
Leonardo de Moura
4ccab41819 test: proof by reflection example 2022-02-20 10:11:40 -08:00
Leonardo de Moura
cf0f7a30c4 test: add Monomials.cancel 2022-02-19 21:29:33 -08:00
Leonardo de Moura
ba16903205 feat: add helper theorems 2022-02-19 21:25:44 -08:00
Leonardo de Moura
855b71299f test: arith by reflection 2022-02-19 17:54:32 -08:00
Leonardo de Moura
193859c72c feat: add helper theorems 2022-02-19 17:53:54 -08:00
Leonardo de Moura
7a13eaea8d chore: update stage0 2022-02-19 08:11:17 -08:00
Leonardo de Moura
7a81589c49 feat: improve "constant approximation" heuristic used at isDefEq 2022-02-19 08:09:31 -08:00
Leonardo de Moura
19bcb5fb31 feat: add Array.popWhile and Array.takeWhile 2022-02-19 07:04:52 -08:00
Leonardo de Moura
a4d6cbfedd feat: improve match elaborator 2022-02-19 06:12:21 -08:00
Leonardo de Moura
f64f563936 chore: fix comment 2022-02-19 06:11:53 -08:00
Leonardo de Moura
e61d0be561 feat: isolate fixed prefix at well-founded recursion
closes #1017
2022-02-18 10:40:32 -08:00
Leonardo de Moura
75e771b6e8 feat: add support for fixed argument prefix at mkFix and elabWFRel
This is needed for #1017

TODO: `addNonRecPreDefs` and equation theorems
2022-02-18 07:59:32 -08:00
Leonardo de Moura
70312191f7 feat: make sure packDomain and packMutual ignore the fixed arguments
TODO: adapt `elabWFRel`, `mkFix`, and etc.

This is needed for #1017
2022-02-17 17:43:06 -08:00
Leonardo de Moura
9ee529e5ce fix: use PSum instead of Sum when using well-founded recursion
See new test for example that did not work with `Sum` because type
alpha was `Sort u`.
2022-02-17 16:14:34 -08:00
Leonardo de Moura
4a0ae8326c feat: compute the fixed prefix size for mutually recursive definitions 2022-02-17 14:12:05 -08:00
Leonardo de Moura
3f0be7901e chore: update stage0 2022-02-17 10:52:34 -08:00
Leonardo de Moura
dedb6ee01b fix: skip value if type is computationally irrelevant 2022-02-17 10:41:16 -08:00
Leonardo de Moura
ba0904060b chore: missing trace_pp_expr 2022-02-17 10:40:21 -08:00
Leonardo de Moura
4ed5c8405b feat: improve IR checker error messages 2022-02-17 09:51:05 -08:00
Leonardo de Moura
6b1297fe85 chore: update stage0 2022-02-16 13:52:28 -08:00
Xubai Wang
ca521e1188 feat: add position to mod doc 2022-02-16 13:50:19 -08:00
Leonardo de Moura
373a64ee09 test: for isNoncomputable 2022-02-16 13:37:49 -08:00
Leonardo de Moura
9d6c26a4a6 chore: update stage0 2022-02-16 13:33:33 -08:00
Leonardo de Moura
e1d9dc4b38 feat: store noncomputable declarations 2022-02-16 13:33:02 -08:00
Leonardo de Moura
31e90c8f65 chore: update stage0 2022-02-16 13:22:44 -08:00
Leonardo de Moura
4ba1e0ad4b feat: add isNoncomputable function for querying whether a given declaration has been marked as "noncomputable" by users 2022-02-16 13:20:31 -08:00
Leonardo de Moura
ad5099ec3c fix: mkLetRecClosureFor for nested let-recs
closes #1020
2022-02-16 12:44:02 -08:00
Leonardo de Moura
86328bcb9f feat: tail recursive List.iota and [csimp] theorem 2022-02-16 11:25:46 -08:00
Leonardo de Moura
d46d246cd9 fix: documentation 2022-02-15 16:19:35 -08:00
Leonardo de Moura
80bb1454c5 doc: add example to RELEASES.md 2022-02-15 16:09:36 -08:00
Leonardo de Moura
3f4d8f370a fix: backtrack InfoTree when backtracking at the discriminant refinement method
This commit addresses issue described at https://github.com/leanprover/lean4/issues/1018#issuecomment-1040597212

closes #1018
2022-02-15 16:01:09 -08:00
Leonardo de Moura
fd9165415e feat: try to preserve variable names during discriminant refinement
This fixes second issue at #1018
2022-02-15 15:54:03 -08:00
Leonardo de Moura
56cdacfc28 feat: allow synthetic holes to be used as patterns
They are useful for getting meaningful pattern variable names when the hole
is not an inaccessible pattern. See new test.

We are going to use this feature to address issue 2 at #1018.
2022-02-15 15:34:14 -08:00
Leonardo de Moura
da1a327d13 chore: remove old comment 2022-02-15 15:01:26 -08:00
Leonardo de Moura
1f230c336b chore: style 2022-02-15 13:32:48 -08:00
Leonardo de Moura
045527daac chore: update stage0 2022-02-15 12:23:11 -08:00
Leonardo de Moura
2435119e6a chore: update stage0 2022-02-15 12:20:34 -08:00
Leonardo de Moura
993ec54db6 chore: avoid hack that may introduce unnecessary dependencies 2022-02-15 12:17:40 -08:00
Leonardo de Moura
e07823bb12 chore: remove unnecessary partial
TODO: we should generate an error/warning when `partial` is not necessary
2022-02-15 12:16:49 -08:00
Leonardo de Moura
a2613a36a4 fix: incorrect dependencies due to assigned variables 2022-02-15 12:15:45 -08:00
Leonardo de Moura
bd89bdde8a fix: core library
see #1018
2022-02-15 12:12:56 -08:00
Leonardo de Moura
df584567f5 feat: (generalizing := true) is the default behavior for match-expressions
closes #1018
2022-02-15 11:12:04 -08:00
Sebastian Ullrich
e9ee9204c4 chore: update Lake 2022-02-15 19:19:19 +01:00
Sebastian Ullrich
54522006f4 refactor: List.get: take Fin to align with Array.get
/cc @leodemoura
2022-02-15 18:41:22 +01:00
Leonardo de Moura
d1e5e4166a feat: use sorry instead of trying to synthesize Inhabited at error recovery 2022-02-15 09:15:18 -08:00
Leonardo de Moura
f75fdcb19b feat: when Lean cannot prove termination, then report error and add definition as partial, and if it fails add as axiom 2022-02-15 07:44:27 -08:00
Sebastian Ullrich
4b03666ecc chore: include orphan file 2022-02-15 09:44:19 +01:00
Leonardo de Moura
f33cb27d1c doc: update RELEASES.md 2022-02-14 15:58:58 -08:00
Leonardo de Moura
66e0b72c6f test: notation for providing names to equality proofs in match expressions is not whitespace sensitivity anymore 2022-02-14 15:51:23 -08:00
Leonardo de Moura
409530306c chore: update stage0 2022-02-14 15:48:11 -08:00
Leonardo de Moura
764a1d9f51 chore: fix tests 2022-02-14 15:47:12 -08:00
Leonardo de Moura
c67ee9fdf4 feat: add pp annotation for match parser 2022-02-14 15:46:52 -08:00
Leonardo de Moura
ffca6975f2 chore: remove bootstrapping workarounds 2022-02-14 15:39:21 -08:00
Leonardo de Moura
42c80c7483 feat: remove whitespace sensitivity at match discriminants 2022-02-14 15:37:40 -08:00
Leonardo de Moura
2a2ad75faa chore: update stage0 2022-02-14 15:37:01 -08:00
Leonardo de Moura
93b5b74b36 feat: modify notation for providing motive in "match" expressions 2022-02-14 15:36:14 -08:00
Leonardo de Moura
0030208d99 chore: prepare to change builtin syntax 2022-02-14 14:17:24 -08:00
Leonardo de Moura
a0fb412989 chore: update stage0
Make sure previous fix is also applied to enumeration types in the
core library.
2022-02-14 12:06:42 -08:00
Leonardo de Moura
07043e73b0 chore: fix tests 2022-02-14 12:06:03 -08:00
Leonardo de Moura
aa63fda835 fix: mark auxiliary noConfusion declarations for enumeration types as [reducible]
closes #1016
2022-02-14 12:03:49 -08:00
Leonardo de Moura
ee9fcd30e8 fix: mark Nat.decEq as [reducible]
It is used by the `noConfusionType` construction for enumeration types,
and we want it to reduce even when the reducibility setting is
`TransparencyMode.reducible` as for other inductive types.

see issue #1016
2022-02-14 12:00:29 -08:00
Leonardo de Moura
93d5351fba feat: display reducibility status at #print 2022-02-14 11:52:41 -08:00
Leonardo de Moura
420d0f2a3f fix: make sure noConfusionTypeEnum and noConfusionEnum fully reduce even reducibility setting is set to TransparencyMode.reducible
The previous definition would not fully reduce since `ite` and `dite`
are not tagged as `[reducible]`.

see issue #1016
2022-02-14 11:39:18 -08:00
Sebastian Ullrich
bdbffdaaf7 chore: update Lake 2022-02-14 16:52:54 +01:00
ammkrn
3de18ceb55 doc: document match h:e with syntax 2022-02-14 15:53:37 +01:00
Sebastian Ullrich
340c331da9 chore: CI: ignore diff exit code 2022-02-13 00:04:08 +01:00
Leonardo de Moura
8be916b0cf doc: update RELEASES.md 2022-02-12 12:08:01 -08:00
Leonardo de Moura
82bce7ebec fix: declare local instaces occurring in patterns 2022-02-12 12:01:08 -08:00
Leonardo de Moura
32dd3c6b29 feat: use at least default transparency at toCtorWhenK
Improves the effectiveness of `simp` when reducing `match`-expr.
2022-02-12 07:56:45 -08:00
Leonardo de Moura
999e80745e test: add test for already fixed issue reported on Zulip 2022-02-12 07:53:31 -08:00
Leonardo de Moura
0649e5fa8a feat: Basic model-based solver for linear arithmetic 2022-02-11 18:38:33 -08:00
Leonardo de Moura
37afafad6e feat: missing Rat functions 2022-02-11 18:24:18 -08:00
Leonardo de Moura
e8c23cdf7e feat: add cache at Lean/Elab/PreDefinition/WF/PackDomain.lean 2022-02-11 09:52:14 -08:00
Leonardo de Moura
9cfa728eac chore: remove workaround for issue #1013 2022-02-11 09:32:29 -08:00
Leonardo de Moura
7b3a674555 chore: update stage0 2022-02-11 09:31:02 -08:00
Leonardo de Moura
ab41dd0d83 test: add test for issue #1013 2022-02-11 09:28:46 -08:00
Leonardo de Moura
123e0f42e9 feat: support partial and over applications at WF/PackDomain.lean
closes #1013
2022-02-11 09:28:17 -08:00
Sebastian Ullrich
2390691116 chore: remove obsolete workaround 2022-02-11 18:19:59 +01:00
Sebastian Ullrich
80e2e1daa8 test: mutual block not needed 2022-02-11 16:22:13 +01:00
Sebastian Ullrich
c460a2e404 chore: CI: fail when uploading 0 files 2022-02-11 10:11:45 +01:00
Sebastian Ullrich
589f05d2c8 chore: CI: do not delete nightly artifacts before uploading them 2022-02-11 10:02:54 +01:00
Leonardo de Moura
77bbaf82df feat: decidable equality for arrays 2022-02-10 17:31:03 -08:00
Leonardo de Moura
a2b7ff9e0d chore: fix doc 2022-02-10 17:12:18 -08:00
Leonardo de Moura
712d6726e4 feat: rename tactic byCases => by_cases 2022-02-10 17:11:07 -08:00
Leonardo de Moura
1491253479 feat: helper simp theorems 2022-02-10 17:06:16 -08:00
Leonardo de Moura
1d5da63482 chore: simplify Array.isEqvAux 2022-02-10 16:51:47 -08:00
Leonardo de Moura
6b6c44c559 feat: add helper lemma 2022-02-10 16:51:32 -08:00
Sebastian Ullrich
894dc0e1b8 fix: pretty-printing match dependent on let 2022-02-10 10:19:04 +01:00
Leonardo de Moura
54473ad523 test: add missing test for issue #998 2022-02-09 18:02:01 -08:00
Leonardo de Moura
9fe0d28107 fix: do not split on if-then-else terms when generating equation theorems
Reason: avoid unnecessary case-analysis explosion
It is also unnecessary since we only refine the `below` and `F`
arguments over `match`-expressions.

This fixes the last case at issue #998
```
attribute [simp] BinaryHeap.heapifyDown
```

closes #998
2022-02-09 17:43:35 -08:00
Leonardo de Moura
c685a2d9ed feat: add splitIte flag to splitTarget? tactic 2022-02-09 17:38:04 -08:00
Leonardo de Moura
7fc12014da fix: make sure splitTarget? skips match expressions that produce type errors at splitMatch
We can now generate the equation theorem for
```
attribute [simp] Array.heapSort.loop
```

see #998
2022-02-09 17:07:10 -08:00
Leonardo de Moura
e574c5373f feat: improve delta? method
Use zeta reduction to create new opportunities of beta-reduction.

This issue fixes on the problems that were affecting the generation of
equation theorems for `Array.heapSort.loop` (see issue: #998).
After this fix, the equation theorem generation fails at `splitMatch`.
2022-02-09 13:31:55 -08:00
Sebastian Ullrich
8cbd7ccf09 test: reimplement package tests using Lake 2022-02-09 12:21:11 -08:00
Leonardo de Moura
15e6dd262d chore: fix tests 2022-02-09 10:13:52 -08:00
Leonardo de Moura
8fbe7062fa fix: preserve unused let-decls at Meta.transform 2022-02-09 10:13:52 -08:00
Leonardo de Moura
3b67c7db81 fix: handling of letrec declarations in the well-founded recursion module 2022-02-09 10:13:52 -08:00
Leonardo de Moura
471ef75345 feat: improve test at packDomain 2022-02-09 10:13:52 -08:00
Leonardo de Moura
e66575d4fc refactor: move and generalize ensureNoRecFn 2022-02-09 10:13:52 -08:00
Leonardo de Moura
1cfe403edf chore: style 2022-02-09 10:13:52 -08:00
Sebastian Ullrich
9e11ea3b34 chore: move test to correct folder 2022-02-09 14:32:18 +01:00
Sebastian Ullrich
a8e34b9310 test: mutual recursion over mutual inductive 2022-02-09 14:24:45 +01:00
Sebastian Ullrich
bdf9472069 chore: fix changelog path... 2022-02-09 09:42:17 +01:00
Leonardo de Moura
2ef0146140 fix: avoid unnecessary matcheApp.addArgs at BRecOn and Fix
It fixes the following two cases from #998
```
attribute [simp] Lean.Export.exportName
attribute [simp] Lean.Export.exportLevel
```
2022-02-08 15:06:14 -08:00
Leonardo de Moura
8692225432 fix: saveEqn at Lean/Elab/PreDefinition/Eqns.lean
see #998
2022-02-08 13:44:49 -08:00
Leonardo de Moura
33ed496661 feat: improve contradiction 2022-02-08 13:26:05 -08:00
Leonardo de Moura
3367f0b06a feat: use splitTarget? when proving equation theorems for recursive definitions 2022-02-08 12:53:09 -08:00
Leonardo de Moura
afb5cb16ee chore: simplify option names
see #1011
2022-02-08 12:23:24 -08:00
Leonardo de Moura
59acf01bc9 feat: relax auto-implicit restrictions
The new options `relaxedAutoBoundImplicitLocal` can be used to
disable this feature.

closes #1011
2022-02-08 12:17:42 -08:00
Leonardo de Moura
398b9c136a chore: fix test 2022-02-08 11:43:45 -08:00
Leonardo de Moura
96336bb44d test: add tests for #998
The previous changes fixed two of them.
2022-02-08 11:43:45 -08:00
Leonardo de Moura
c486203481 fix: use simpTargetStar when proving equation theorems for recursive definitions
Add `take` function reported at Zulip.
2022-02-08 11:43:45 -08:00
Leonardo de Moura
c1777c17e3 feat: add simpTargetStar 2022-02-08 11:43:45 -08:00
Leonardo de Moura
824d0aa8a5 chore: remove leftover 2022-02-08 11:43:45 -08:00
Sebastian Ullrich
ad80c69cba chore: CI: add RELEASES.md diff to nightly description 2022-02-08 14:25:54 +01:00
Sebastian Ullrich
e45830f8b3 chore: CI: release only if all jobs finished successfully 2022-02-08 14:25:54 +01:00
Leonardo de Moura
e626b3d4aa chore: make it clear that v4.0.0-m4 has not been released yet 2022-02-07 17:59:46 -08:00
Leonardo de Moura
a9bb646d4f chore: cleanup 2022-02-07 17:35:07 -08:00
Leonardo de Moura
aa2d547c2b doc: add last item at congr theorem whishlist
closes #988
2022-02-07 17:26:43 -08:00
Leonardo de Moura
8d7f0ea2f2 feat: add removeUnnecessaryCasts
see #988
2022-02-07 17:24:32 -08:00
Leonardo de Moura
9d34d9bc5a feat: cache and optimize mkCongrSimp? at simp
see #988
2022-02-07 17:01:21 -08:00
Leonardo de Moura
007f0e1d71 feat: use mkCongrSimp? at simp
TODO: cache auto generated congr theorems, and `removeUnnecessaryCasts`

see #988
2022-02-07 16:45:01 -08:00
Leonardo de Moura
93bd4a7f88 chore: lemma => thm 2022-02-07 13:55:23 -08:00
Leonardo de Moura
6f7fb9ccaf chore: update stage0 2022-02-07 13:19:52 -08:00
Leonardo de Moura
5baac1905f fix: use private names for theorems that are created on demand
closes #1006
2022-02-07 13:16:22 -08:00
ammkrn
efb533fb24 doc: document some do block patterns/sugar 2022-02-07 20:50:15 +01:00
Leonardo de Moura
eff63632b3 feat: improve error message when max heartbeats is reached during TC
see #1007
2022-02-07 11:23:48 -08:00
Gabriel Ebner
f8b43630a6 fix: refs to copied subobjects in diamond extension 2022-02-07 10:54:32 -08:00
Sebastian Ullrich
4e77b6a615 doc: extend RELEASES.md 2022-02-07 11:31:58 +01:00
Leonardo de Moura
e8781ad889 chore: update stage0 2022-02-06 09:17:40 -08:00
Leonardo de Moura
8cea32f42d chore: fix test 2022-02-06 09:15:39 -08:00
Leonardo de Moura
9c2942c36d chore: "simp lemma" => "simp theorem" 2022-02-06 09:15:39 -08:00
Leonardo de Moura
d6dc077c86 refactor: CongrLemma => SimpCongrTheorem 2022-02-06 09:15:39 -08:00
Leonardo de Moura
96bae46045 refactor: SimpLemma => SimpTheorem 2022-02-06 09:15:39 -08:00
Sebastian Ullrich
2c7d67d498 fix: make info of fields synthesized by structure update synthetic 2022-02-06 08:50:07 -08:00
Leonardo de Moura
255db2b47d chore: update stage0 2022-02-06 08:12:21 -08:00
Joscha
196cf67eed fix: handle overlapping definitions 2022-02-06 16:52:18 +01:00
Leonardo de Moura
f78d355416 chore: style 2022-02-06 07:29:26 -08:00
Leonardo de Moura
e35235eec5 chore: update stage0 2022-02-06 07:24:22 -08:00
Sebastian Ullrich
0ef5985b5f fix: binder info range for let rec/where 2022-02-06 07:21:51 -08:00
Patrick Stevens
b48e48328f chore: Nix: bump vscode-lean4 version to 0.0.63 2022-02-05 20:08:45 +01:00
Joscha
841d51a7e6 fix: walkDir 2022-02-05 19:55:09 +01:00
Sebastian Ullrich
06e81637fe fix: symlinking src/ into build directory 2022-02-05 18:52:40 +01:00
Leonardo de Moura
7f0060b214 chore: update stage0 2022-02-04 18:25:35 -08:00
Leonardo de Moura
6de0b1fc67 feat: add mkCongrSimp.mkProof
see #988
2022-02-04 17:57:28 -08:00
Leonardo de Moura
3ae455bccf feat: add mkCongrSimp?
TODO: proof is still missing

see #988
2022-02-04 17:57:28 -08:00
Leonardo de Moura
a028a69159 feat: cache isProp and isDecInst at FunInfo 2022-02-04 17:57:28 -08:00
Wojciech Nawrocki
5668e2644a fix: typo 2022-02-04 12:55:53 -08:00
Sebastian Ullrich
a7ba103e0a chore: remove leanpkg 2022-02-04 19:03:40 +01:00
Sebastian Ullrich
2b7427c962 chore: adjust changelog merge strategy config
/cc @leodemoura
2022-02-04 18:32:20 +01:00
Leonardo de Moura
cfb67ee589 chore: add RELEASES.md
It is based on the approach used in rust.
2022-02-04 09:24:20 -08:00
Sebastian Ullrich
ae062c6ead fix: match tactic should not trigger implicit lambdas 2022-02-04 07:55:56 -08:00
Sebastian Ullrich
7fd76cd1b9 chore: CI: fix sanitizer test excludes
Apparently StackOverflow got fixed at some point?
2022-02-04 15:01:30 +01:00
Mario Carneiro
6e7d76f4d8 fix: typo 2022-02-03 18:21:14 -08:00
Leonardo de Moura
95aec2cf93 chore: update stage0 2022-02-03 18:10:10 -08:00
Leonardo de Moura
1684cfec83 chore: update lake 2022-02-03 18:09:48 -08:00
Leonardo de Moura
12e2a79170 chore: fix codebase after removing auto pure 2022-02-03 18:08:14 -08:00
Leonardo de Moura
00f59a91ee chore: update stage0 2022-02-03 17:07:14 -08:00
Leonardo de Moura
e9d85f49e6 chore: remove tryPureCoe?
Based on the discussion at
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/for.2C.20unexpected.20need.20for.20type.20ascription/near/269083574
The consensus seemed to be that "auto pure" is more confusing than its worth.
2022-02-03 16:25:24 -08:00
Leonardo de Moura
6d07092d1e chore: update stage0 2022-02-03 15:56:28 -08:00
Leonardo de Moura
5f74cd4968 feat: add let pat := val | elseCase do-notation 2022-02-03 15:55:03 -08:00
Leonardo de Moura
420f5bb315 fix: hide internal namespaces from autocompletion
closes #993
2022-02-03 13:33:27 -08:00
Leonardo de Moura
17eab845ed fix: improve tryPostponeIfMVar
see #992
2022-02-03 13:24:19 -08:00
Leonardo de Moura
2bc5b8d1ec chore: remove doc/changes.md
In the last dev meeting, we have decided we are not going to use it.
We will release often (every month), and use pull requests and issues
to report changes.
2022-02-03 09:23:45 -08:00
Leonardo de Moura
42b3ed5903 test: add Pi.single test
see #988
2022-02-03 09:22:22 -08:00
Sebastian Ullrich
22526051e0 fix: install sources to src/lean/, not lib/lean
Not only is this more semantically appropriate (see e.g.
`/usr/src/{linux,rust,...}` on Debian), it also prevents .ilean files
from Lake tests (which are symlinked into the build directory as part of
`src/` during development) from ending up in the built-in LEAN_PATH and
being watched & loaded by the server.
2022-02-03 18:20:21 +01:00
Gabriel Ebner
55be278cd7 fix: ensure motive of matches is Bool 2022-02-03 18:17:27 +01:00
Gabriel Ebner
54cff10f3f fix: dependent fields in diamond extensions 2022-02-03 09:17:14 -08:00
Leonardo de Moura
c30380e2fa feat: lift the restriction in congr theorems that all function arguments on the lhs must be free variables
see #988
2022-02-02 18:23:18 -08:00
Leonardo de Moura
b7c853692d test: add test for decide congruence issue
TODO: congruence lemma must be automatically generated.

see #988
2022-02-02 17:49:03 -08:00
Leonardo de Moura
101fc12b54 feat: partially applied user congruence lemmas
see #988
2022-02-02 17:41:21 -08:00
Leonardo de Moura
dbb6dcd9a9 fix: remove irrelevant hypotheses in auto-generated equation theorems 2022-02-02 15:39:51 -08:00
Leonardo de Moura
188f0eb70f fix: splitMatch tactic
Improve how we compute the motive for match-splitter eliminator.

closes #986
2022-02-02 15:06:03 -08:00
Leonardo de Moura
d7f085976f feat: add Coe MVarId MessageData 2022-02-02 15:06:03 -08:00
Leonardo de Moura
4a4074baab fix: only generalize when needed at cases 2022-02-02 15:06:03 -08:00
Leonardo de Moura
4fe56d2a9d fix: allow mkElimApp to assign new goals when solving typing constraints 2022-02-02 15:06:03 -08:00
Leonardo de Moura
65e1fc1211 feat: at splitMatch only generalize discriminants that are not FVar 2022-02-02 15:06:03 -08:00
Leonardo de Moura
630bf4e129 chore: update error message for throwNestedTacticEx 2022-02-02 15:06:03 -08:00
Leonardo de Moura
3101b98f50 feat: used nested tactic exception at splitMatch 2022-02-02 15:06:03 -08:00
Sebastian Ullrich
16f6b19e21 fix: silence .ilean load errors 2022-02-02 22:02:15 +01:00
Sebastian Ullrich
e400b02a05 test: wrong test 2022-02-02 13:17:30 +01:00
Sebastian Ullrich
3425278d97 test: forgot to commit test for #801 2022-02-02 13:08:23 +01:00
larsk21
ce92672c3a fix: remove explicit Ord Range 2022-02-02 13:03:21 +01:00
larsk21
e73645505b fix: remove duplicate from interactive highlight test 2022-02-02 13:03:21 +01:00
larsk21
6cee7a6a31 fix: dedup references in findModuleRefs 2022-02-02 13:03:21 +01:00
larsk21
818e8acd0e feat: add test for handleDocumentHighlight 2022-02-02 13:03:21 +01:00
larsk21
bc65da2e83 feat: extend handleDocumentHighlight 2022-02-02 13:03:21 +01:00
Leonardo de Moura
3dfd14dfff chore: fix test 2022-01-31 16:45:57 -08:00
Leonardo de Moura
b1617fe04c feat: add throwNestedTacticEx
closes #194
2022-01-31 16:25:44 -08:00
Leonardo de Moura
ccddd0d932 feat: show proof state/unclosed goal message on empty tactic sequences
closes #361
2022-01-31 16:22:08 -08:00
Leonardo de Moura
9291f59c8f chore: add changes.md 2022-01-31 15:52:28 -08:00
Sebastian Ullrich
6f28d70d50 chore: CI: fix non-release jobs on release 2022-01-31 22:59:07 +01:00
Leonardo de Moura
f02013fd76 fix: induction MetaM tactic
The major premise may be a let-declaration.

closes #983
2022-01-31 13:41:38 -08:00
Joscha
d2dcff1f9a refactor: address review comments 2022-01-31 21:36:37 +01:00
Joscha
bfc185e98e fix: don't duplicate definition and declaration requests 2022-01-31 21:36:37 +01:00
Joscha
4545e183d8 fix: go to definition in modified file 2022-01-31 21:36:37 +01:00
Joscha
ccf492b61d feat: implement partial ilean updates 2022-01-31 21:36:37 +01:00
tydeu
768e8f76ec chore: update Lake 2022-01-31 14:31:31 +01:00
Sebastian Ullrich
dfc19755cb chore: CI: fsan-blacklist laketest_ffi as well 2022-01-31 14:29:12 +01:00
Sebastian Ullrich
f3279824a3 fix: Windows: do not use standard sysroot 2022-01-30 17:43:14 +01:00
Sebastian Ullrich
f9ff9ab3fd doc: move documentation on syntax match semantics to elaborator docstring 2022-01-29 08:40:03 -08:00
Sebastian Ullrich
ce58ded16f fix: syntax match of literals
Fixes #801
2022-01-29 08:40:03 -08:00
Gabriel Ebner
7d4ae642fb fix: recursively copy subfields in diamond extends 2022-01-29 08:31:34 -08:00
Sebastian Ullrich
4d17f1ccb3 chore: CI: rename Nix job to make available to branch protection rule 2022-01-29 17:30:01 +01:00
Wojciech Nawrocki
2d1cea0864 feat: inform server if widgets are available 2022-01-29 10:04:25 +01:00
Leonardo de Moura
3db640e770 chore: avoid Name.quickLt
`Name.quickLt` uses hash code and may produce counterintuitive results
to users.
2022-01-28 09:48:50 -08:00
Leonardo de Moura
e5ef61225b fix: missing condition at lpo case 3 2022-01-28 09:47:35 -08:00
Leonardo de Moura
cb4a86ac68 fix: do not validate local eq theorems
see #973
2022-01-27 11:50:20 -08:00
Leonardo de Moura
d4d9995952 feat: reject user declared namespaces containing _root
see #490
2022-01-26 19:15:45 -08:00
Leonardo de Moura
941a6165e5 chore: cleanup 2022-01-26 18:26:23 -08:00
Leonardo de Moura
a63163e992 feat: do not try to discharge hypotheses at simp when type contains assignable metavariables
closes #973
see https://github.com/leanprover-community/mathport/issues/70
2022-01-26 17:57:52 -08:00
Leonardo de Moura
2fff4c42b7 fix: make sure irreducible constants are not unfolded when using the default reducibility setting 2022-01-26 11:55:21 -08:00
Leonardo de Moura
8db923e010 feat: generate error message for simp theorems that are equivalent to x = x
see #973
see https://github.com/leanprover-community/mathport/issues/70
2022-01-26 11:16:31 -08:00
Leonardo de Moura
36d7f2a1ea chore: remove dead code 2022-01-26 10:38:46 -08:00
Leonardo de Moura
cf3b8d4eb4 chore: cleanup
Make the code style more uniform.
We still have a lot of leftovers from the old frontend.
2022-01-26 09:18:17 -08:00
Leonardo de Moura
f0b502aca6 fix: increase the number of heartbeats at Expr.eqv
On issue #906, `simp` spends a lot of time checking the cache. This
process is time consuming and doesn't allocate memory. Before this
commit, it would take a long time to get the "maximum number of
heartbeats" error message on the example included in this issue.

Closes #906
2022-01-26 08:25:33 -08:00
Leonardo de Moura
a10e32f537 fix: check "heartbeats" at simp 2022-01-26 07:50:25 -08:00
Leonardo de Moura
15cca3000a fix: withIncRecDepth was not aborting simp
It was just making it stop simplification at the current branch.

Now, elaboration is interrupted after a few seconds in the example at
issue #906.

see #906
2022-01-26 07:48:58 -08:00
Leonardo de Moura
868e95df1b feat: add Exception.isMaxRecDepth 2022-01-26 07:38:38 -08:00
Leonardo de Moura
8896c9b06d test: add variant of Formula.count_quantifiers
see #974
2022-01-25 18:47:03 -08:00
Leonardo de Moura
98407798af fix: mkEquationsFor at Match/MatchEqs.lean
closes #974
2022-01-25 18:43:51 -08:00
Leonardo de Moura
a969014eb9 chore: add matchHEq? 2022-01-25 18:43:51 -08:00
Leonardo de Moura
9c293abb9c chore: expose heqToEq tactic 2022-01-25 18:43:51 -08:00
Leonardo de Moura
6547af988b feat: add substVars 2022-01-25 18:43:51 -08:00
Sebastian Ullrich
2f02ddeba1 fix: Nix: revise propagation of load-dynlibs 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
cf1654df1f fix: Nix: precompilation against stdlib, once more 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
180cc59d64 chore: update Lake to https://github.com/leanprover/lake/pull/48/files 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
cfaba85199 feat: load precompiled modules in the server 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
a926c6b1b2 chore: Nix: more consistent drv name 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
8893ba9fa0 fix: Nix: precompilation on macOS 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
9b87428555 fix: Nix: work around https://github.com/NixOS/nixpkgs/issues/148189 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
23db584b8f fix: Nix: precompilation against stdlib 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
b601f2ffb2 perf: Nix: use bare command for shared libs 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
096250a585 feat: Nix: simple, opt-in precompilation scheme 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
01987dbc8e refactor: Nix: attach object drv to module drv 2022-01-25 23:25:52 +01:00
Sebastian Ullrich
ac28f89527 fix: Nix: link package's shared library dynamically against dependencies
refactor: Nix: dynlib handling
2022-01-25 23:25:52 +01:00
Leonardo de Moura
234f70fadb chore: remove the now incorrect comment 2022-01-24 19:05:05 -08:00
Leonardo de Moura
02677cf326 fix: igore instance implicit arguments in term ordering used at simp
closes #972
2022-01-24 18:57:31 -08:00
Leonardo de Moura
d4f7899591 chore: avoid code duplication setting Simp.Config 2022-01-24 18:57:31 -08:00
Sebastian Ullrich
b20ecd02d7 chore: move out lean4-mode 2022-01-24 21:23:53 +01:00
Leonardo de Moura
722bf54929 fix: trace message with incorrect MetavarContext 2022-01-24 10:34:44 -08:00
Leonardo de Moura
7ada79bf2e fix: use an AC-compatible ordering on Expr at simp
closes #968
2022-01-22 09:42:59 -08:00
Leonardo de Moura
763a337c25 chore: helper functions 2022-01-22 09:30:57 -08:00
Leonardo de Moura
d096f59f86 chore: update stage0 2022-01-22 08:06:31 -08:00
Leonardo de Moura
0615020cf7 feat: make sure Expr.approxDepth does not overflow 2022-01-22 07:45:19 -08:00
Tom Ball
0b140ea451 doc: fix error in manual example
Co-authored-by: Tom Ball <you@example.com>
2022-01-22 10:03:32 +01:00
Sebastian Ullrich
fb57b73e1f fix: Nix: compatibility with standard build 2022-01-21 09:24:43 +01:00
Leonardo de Moura
79dec8fa7c chore: fix test 2022-01-20 17:19:29 -08:00
Leonardo de Moura
253f3aa5ec chore: update stage0 2022-01-20 17:16:50 -08:00
Leonardo de Moura
d39025e343 test: add test for issue #951 2022-01-20 17:16:06 -08:00
Leonardo de Moura
893b816f82 chore: update stage0 2022-01-20 17:11:09 -08:00
Leonardo de Moura
b0083e0dd0 feat: use elaborated type to generate instance name
closes #951
2022-01-20 17:09:55 -08:00
Leonardo de Moura
a9659afa50 chore: remove old decls 2022-01-20 15:35:19 -08:00
Leonardo de Moura
70de6dabb3 chore: update stage0 2022-01-20 15:33:45 -08:00
Leonardo de Moura
6f416147b4 chore: rename coeM and liftCoeM 2022-01-20 15:33:17 -08:00
Leonardo de Moura
0c959b6942 chore: fix tests 2022-01-20 15:25:59 -08:00
Leonardo de Moura
2192e6148b chore: remove coe, coeSort, and coeFun abbreviations
The notation `↑ e` is now expanded eagerly.

See #403
2022-01-20 15:19:06 -08:00
Leonardo de Moura
7c0a790774 chore: update stage0 2022-01-20 15:10:13 -08:00
Leonardo de Moura
3c17755730 chore: prepare to remove coe definitions
The notation `↑ e` will eagerly expand the coersion.

See #403
2022-01-20 15:07:54 -08:00
Leonardo de Moura
f9fa24435d chore: remove problematic instance hasOfNatOfCoe
See #403
See https://github.com/leanprover-community/mathport/issues/94
2022-01-20 14:47:25 -08:00
Sebastian Ullrich
f0f26728ed doc: more about initializers 2022-01-20 18:55:57 +01:00
Sebastian Ullrich
dc148003cb chore: Nix: remove annoying output 2022-01-20 18:55:57 +01:00
Sebastian Ullrich
52de670497 chore: clarify safety of compile-time code execution 2022-01-20 18:55:57 +01:00
Sebastian Ullrich
c59f7a55cf fix: initialize precompiled modules 2022-01-20 18:55:57 +01:00
Leonardo de Moura
e7dd03d5d1 chore: remove tmp dir 2022-01-20 09:54:28 -08:00
Leonardo de Moura
b1a92f5cbf feat: better Repr instances for Level.Data and Expr.Data
see #619
2022-01-20 09:45:30 -08:00
Leonardo de Moura
ff4be1e1db feat: add Repr instances for Level and Expr
closes #619

TODO: a better `Repr` instance for `Expr.Data`
2022-01-20 09:26:06 -08:00
Leonardo de Moura
d190d6dda4 fix: use default reducibility when proving equation theorems for definition
Addresses issue reported by @fpfu at #945
2022-01-20 08:23:51 -08:00
Joscha
9949f92648 refactor: base findModuleWithExt on findWithExt 2022-01-20 17:20:01 +01:00
Joscha
2423a78db4 refactor: implement suggestions 2022-01-20 17:20:01 +01:00
Sebastian Ullrich
3a926b1047 fix: use user-facing private decl name in symbol query 2022-01-20 17:20:01 +01:00
Sebastian Ullrich
53d90a71ae feat: do case-sensitive symbol query if query contains upper-case char 2022-01-20 17:20:01 +01:00
Sebastian Ullrich
1168334cca fix: Unicode symbol lookup 2022-01-20 17:20:01 +01:00
Joscha
7540889bd3 feat: implement LSP workspace symbol request 2022-01-20 17:20:01 +01:00
Sebastian Ullrich
ccf1292e07 fix: rework header/lib handling with bundled clang
* use `-nostdinc` to make sure system headers don't affect us
* include clang headers with `-isystem`, which suppresses all those warnings
* do not use default sysroot on Windows after all, since that can be a
  surprising location

Fixes #922
2022-01-20 16:05:54 +01:00
Leonardo de Moura
f5509ab867 fix: equational lemma generation for definitions using named patterns
closes #945
2022-01-19 17:45:54 -08:00
Leonardo de Moura
ef449e816f chore: improve trace messages 2022-01-19 14:29:04 -08:00
Sebastian Ullrich
bbec84bb18 chore: more output on trace.Elab.info 2022-01-19 21:40:29 +01:00
Joscha
3651ebb377 fix: don't send worker notification to client 2022-01-19 16:29:10 +01:00
Sebastian Ullrich
89e460dd1b chore: CI: push .ileans to Cachix 2022-01-19 12:35:42 +01:00
Sebastian Ullrich
312944e784 fix: hover etc. on complex declaration name 2022-01-19 12:27:03 +01:00
tydeu
8e79d88d29 feat: liftOption 2022-01-19 12:22:05 +01:00
Leonardo de Moura
873a2ba8a6 feat: unfold namedPattern applications at equation theorems 2022-01-18 15:03:20 -08:00
Leonardo de Moura
1e21815e41 fix: equality theorem generation when named patterns are used
closed #945
2022-01-18 14:37:51 -08:00
Leonardo de Moura
c816524d8d feat: add subst? 2022-01-18 14:26:14 -08:00
Leonardo de Moura
c12fa6f0e2 fix: error message
The equation theorems may fail for other reasons.
2022-01-18 14:11:54 -08:00
Leonardo de Moura
a21265281b chore: remove temporary workaround 2022-01-18 14:11:54 -08:00
Arthur Paulino
98289ed3d7 feat: provide functions to build a HashMap from a List of key-value pairs
As a motivation, programming languages that implement hash maps usually provide an interface for easy instantiation.

Closes 947
2022-01-18 22:51:00 +01:00
Leonardo de Moura
63025663fd chore: update stage0 2022-01-18 12:47:36 -08:00
Leonardo de Moura
ab5e43acaa chore: update stage0 2022-01-18 12:45:27 -08:00
Leonardo de Moura
1c1e6d79a7 feat: add equality proof for named patterns
The user can optionally name the equality proof.
The new test demostrates how to name the equality proof.

closes #501
2022-01-18 12:43:01 -08:00
Leonardo de Moura
42fe01a3eb feat: add new flag to caseValues 2022-01-18 12:15:29 -08:00
Leonardo de Moura
8058bc894c feat: add AssocList.toList 2022-01-18 11:44:43 -08:00
Leonardo de Moura
cd903bde77 refactor: [s : Setoid α] => {s : Setoid α} or (s : Setoid α)
See comment at https://github.com/leanprover/lean4/issues/952#issuecomment-1015265136

cc @gebner
2022-01-18 09:24:06 -08:00
Leonardo de Moura
9d05023325 chore: remove some [specialize] annotations 2022-01-18 09:24:06 -08:00
Sebastian Ullrich
3abb70dbb5 refactor: factor out common source search path logic 2022-01-18 18:22:50 +01:00
Leonardo de Moura
b266961068 chore: fix test 2022-01-17 17:24:09 -08:00
Leonardo de Moura
4ac019ccf0 chore: update stage0 2022-01-17 17:22:02 -08:00
Leonardo de Moura
874aadd7e3 chore: update namedPattern signature
Remark: It is not being used yet.
2022-01-17 17:21:18 -08:00
Leonardo de Moura
35d25dfaaf chore: update stage0 2022-01-17 17:18:49 -08:00
Leonardo de Moura
6631f1d5b3 chore: use namedPatternOld 2022-01-17 17:18:03 -08:00
Leonardo de Moura
db9bb8dd1b chore: update stage0 2022-01-17 17:14:46 -08:00
Leonardo de Moura
0f217eb4c1 chore: prepare to change namedPattern signature 2022-01-17 17:13:09 -08:00
Leonardo de Moura
2a17233f1c chore: fix test 2022-01-17 17:07:08 -08:00
Leonardo de Moura
2c0da66ff2 chore: update stage0 2022-01-17 17:04:44 -08:00
Leonardo de Moura
be4c86f780 chore: remove temporary workarounds 2022-01-17 17:03:15 -08:00
Leonardo de Moura
05b9240c72 chore: update stage0 2022-01-17 16:59:20 -08:00
Leonardo de Moura
f8653a8cb7 chore: add temporary workaround 2022-01-17 16:58:39 -08:00
Leonardo de Moura
b142f709e1 chore: update stage0 2022-01-17 16:55:31 -08:00
Leonardo de Moura
2c690926cf feat: update namedPattern parser 2022-01-17 16:49:20 -08:00
Leonardo de Moura
de11f7e1bc feat: add sizeOf spec lemmas as simp theorems 2022-01-17 16:14:38 -08:00
Leonardo de Moura
8f47043aee chore: add trace message for sizeOf theorem 2022-01-17 15:42:42 -08:00
Gabriel Ebner
ab276a5ae3 chore: show declaration with sorry in #eval 2022-01-17 13:18:22 -08:00
Leonardo de Moura
03a5c5034f chore: update stage0 2022-01-17 13:10:09 -08:00
Leonardo de Moura
a272b222f1 chore: update stage0 2022-01-17 13:08:00 -08:00
Leonardo de Moura
999e125e3f feat: mark arguments such as {_ : BEq α} as specialization target
We want to specialize functions such as
```
def find? {_ : BEq α} {_ : Hashable α} : PersistentHashMap α β → α → Option β
  | { root := n, .. }, k => findAux n (hash k |>.toUSize) k
```
2022-01-17 13:05:50 -08:00
Gabriel Ebner
561a869e49 fix: provide reference implementation for Array.modify 2022-01-17 12:41:12 -08:00
Leonardo de Moura
dd3d8f6fad feat: complete namespaces
closes #940
2022-01-17 10:03:36 -08:00
Leonardo de Moura
da06bb6605 fix: matching inside new termination_by 2022-01-17 08:47:05 -08:00
Leonardo de Moura
98af42077c chore: fix doc 2022-01-16 09:28:03 -08:00
Leonardo de Moura
189f4bd372 chore: fix tests 2022-01-15 12:18:09 -08:00
Leonardo de Moura
bac91b9b5b chore: remove arbitrary 2022-01-15 12:14:27 -08:00
Leonardo de Moura
20d5b5b9c0 chore: update stage0 2022-01-15 12:03:17 -08:00
Leonardo de Moura
579908e9b1 chore: using Inhabited.default at Deriving/Inhabited 2022-01-15 11:59:43 -08:00
Leonardo de Moura
7d5f14b4a7 chore: elaborate default_or_ofNonempty% and add mkDefault 2022-01-15 11:55:58 -08:00
Leonardo de Moura
5c69d63157 chore: update stage0 2022-01-15 11:52:40 -08:00
Leonardo de Moura
9de58c66eb chore: add default_or_ofNonempty% 2022-01-15 11:50:39 -08:00
Leonardo de Moura
a3a134a297 chore: export Inhabited.default 2022-01-15 11:50:28 -08:00
Leonardo de Moura
c1fccf19cb chore: fix test 2022-01-15 11:46:11 -08:00
Leonardo de Moura
901c0dba83 chore: update lake 2022-01-15 11:44:40 -08:00
Leonardo de Moura
b0d9c16c7a chore: rename PointedType => NonemptyType 2022-01-15 11:43:53 -08:00
Henrik Böving
c1b31a57eb feat: store ModuleData of imported modules in EnvironmentHeader 2022-01-15 10:40:52 -08:00
tydeu
07bfdc02e7 chore: update Lake 2022-01-15 17:57:51 +01:00
Leonardo de Moura
5e462f704a chore: update stage0 2022-01-14 20:43:22 -08:00
Leonardo de Moura
83b616ad07 chore: update lake 2022-01-14 20:42:36 -08:00
Leonardo de Moura
e3241e82bc feat: define PointedType as { α : Type u // Nonempty α } 2022-01-14 20:36:51 -08:00
Leonardo de Moura
23e27f657f chore: update stage0 2022-01-14 20:29:26 -08:00
Leonardo de Moura
6ea0aaf35a fix: do not invoke add_extern for declarations marked with implementedBy 2022-01-14 20:27:50 -08:00
Leonardo de Moura
9499cea2a5 fix: bug at skip_code_generation 2022-01-14 19:58:24 -08:00
Leonardo de Moura
42db1f09d2 chore: update lake 2022-01-14 19:49:30 -08:00
Leonardo de Moura
b970919978 chore: remove unnecessary Inhabited 2022-01-14 19:48:10 -08:00
Leonardo de Moura
acd482c5f2 feat: define Array.modify without using Inhabited 2022-01-14 19:47:42 -08:00
Leonardo de Moura
9c5668515c chore: update stage0 2022-01-14 19:21:29 -08:00
Leonardo de Moura
b22a3a4cc4 feat: skip code generation for declarations marked with implementedBy, init, and builtinInit
This is a bit hackish. We should clean up when we rewrite the compiler
in Lean.
2022-01-14 19:20:16 -08:00
Leonardo de Moura
a438a2ee21 feat: elaborate arbitrary_or_ofNonempty% and use it to define constants 2022-01-14 17:22:39 -08:00
Leonardo de Moura
2fe59456fd chore: update stage0 2022-01-14 17:19:34 -08:00
Leonardo de Moura
0a726a755f feat: add helper parser arbitrary_or_ofNonempty% 2022-01-14 17:11:55 -08:00
Leonardo de Moura
226d828e19 chore: update stage0 2022-01-14 16:51:05 -08:00
Leonardo de Moura
c34adb7dd5 feat: allow partial definitions to be define if type is non empty 2022-01-14 16:50:36 -08:00
Leonardo de Moura
f1adedb2de feat: add Classical.ofNonempty 2022-01-14 15:59:11 -08:00
Leonardo de Moura
83b69bc340 refactor: move Classical.choice and Nonempty to Prelude 2022-01-14 15:59:11 -08:00
Sebastian Ullrich
9ab5f0376e feat: Nix: iTree attribute for symlinking (complete) ilean files 2022-01-14 19:02:10 +01:00
Sebastian Ullrich
753e396705 fix: recurse in findAllWithExt 2022-01-14 18:59:58 +01:00
Sebastian Ullrich
6ec406b7d0 feat: System.FilePath.walkDir 2022-01-14 16:22:14 +01:00
larsk21
b712918db9 fix: unify handleDefinition for imports 2022-01-14 10:32:06 +01:00
larsk21
ecaa004dcc feat: make withWaitFindSnap consider all snaps of a document 2022-01-14 10:32:06 +01:00
larsk21
e584560b17 feat: enable "go to definition" for imports 2022-01-14 10:32:06 +01:00
larsk21
89bbaf514e feat: include imports in header snap info tree 2022-01-14 10:32:06 +01:00
Joscha
6d809e7cd1 test: remove references test
This test no longer works since the 'references' request now requires at
least a watchdog, but this kind of test only work with file workers.
2022-01-14 09:18:57 +01:00
Sebastian Ullrich
8e5fc66330 fix: do not error on non-existent search path entries 2022-01-14 09:18:57 +01:00
Sebastian Ullrich
a0e8c6183b fix: parser should create choice node even on error 2022-01-14 09:18:57 +01:00
Joscha
8c5868e106 perf: reduce size of ilean files 2022-01-14 09:18:57 +01:00
Sebastian Ullrich
37f5be1b26 chore: fix servertest_init_exit 2022-01-14 09:18:57 +01:00
Sebastian Ullrich
d503fe6d13 refactor: avoid double exception layer with AsyncList 2022-01-14 09:18:57 +01:00
Joscha
d8ec900ae9 refactor: use array instead of list in AsyncElabState 2022-01-14 09:18:57 +01:00
Joscha
ab52480b69 fix: implement suggestions 2022-01-14 09:18:57 +01:00
Joscha
4bcf7ab31f style: add copyright headers 2022-01-14 09:18:57 +01:00
Joscha
b9f8f5eb38 fix: find references of function parameters 2022-01-14 09:18:57 +01:00
Joscha
281ede6ed4 feat: handle references notifications 2022-01-14 09:18:57 +01:00
Joscha
f98cf0289c feat: send references notification when file evaluation finishes 2022-01-14 09:18:57 +01:00
Joscha
7cce91acb4 refactor: move some reference-related types to Lean.Data
These types are required for worker->watchdog notifications.
2022-01-14 09:18:57 +01:00
Joscha
088433dc57 refactor: let AsyncList creation be stateful 2022-01-14 09:18:57 +01:00
Joscha
67aa823ae2 fix: resolve symlinks for the LSP client 2022-01-14 09:18:57 +01:00
Joscha
bce56fdc0c feat: implement reference request 2022-01-14 09:18:57 +01:00
Joscha
7abdf94fc5 feat: respond to reference request in watchdog 2022-01-14 09:18:57 +01:00
Joscha
4fd1d22c31 feat: load and unload ileans on LSP notifications 2022-01-14 09:18:57 +01:00
Joscha
4e12cc902b feat: load ilean files from olean search path 2022-01-14 09:18:57 +01:00
Joscha
567a854a15 feat: load search path for source files in watchdog 2022-01-14 09:18:57 +01:00
Joscha
87b8afff6b feat: register file watcher for .ilean files 2022-01-14 09:18:57 +01:00
Joscha
bcc499b7c0 feat: build .ilean files next to .olean files 2022-01-14 09:18:57 +01:00
Joscha
346b50a22e chore: update stage0 2022-01-14 09:18:57 +01:00
Joscha
3f998c68bc feat: export reference info to ilean files 2022-01-14 09:18:57 +01:00
Joscha
96ed620933 feat: collect reference info from InfoTrees 2022-01-14 09:18:57 +01:00
Joscha
efb964956e feat: add FileRefMap and convert to/from JSON 2022-01-14 09:18:57 +01:00
Joscha
fead5526bc feat: add -i cli option 2022-01-14 09:18:57 +01:00
Simon Hudon
ec3cc0cc45 feat: lean-mode: auto-select lean 3 mode 2022-01-14 09:17:34 +01:00
Leonardo de Moura
6d235586f0 fix: ignore TC failures while processing patterns
closes #948
2022-01-13 10:55:09 -08:00
Leonardo de Moura
1620987b6c fix: recursive applications in discriminants 2022-01-13 09:56:33 -08:00
Sebastian Ullrich
b56fa81b70 chore: CI: sanitizer-blacklist Lake test again
Apparently 1500s are not sufficient for termination...
2022-01-13 17:10:07 +01:00
Leonardo de Moura
8c45c844aa test: add wellfounded test 2022-01-12 17:16:43 -08:00
Leonardo de Moura
3fbf5acbee fix: add missing [reducible] annotations Init/WF.lean 2022-01-12 17:12:55 -08:00
Leonardo de Moura
98864f707e test: add test for #879
The new `termination_by` syntax should address issue #879

closes #879
2022-01-12 16:25:09 -08:00
Leonardo de Moura
7fe6881c42 feat: use new termination_by syntax 2022-01-12 16:23:25 -08:00
Leonardo de Moura
35a49ca535 chore: update stage0 2022-01-12 16:23:25 -08:00
Leonardo de Moura
9162901c86 fix: expandTerminationByNonCore 2022-01-12 16:22:54 -08:00
Leonardo de Moura
91a0ac8a12 feat: elaborate new termination_by syntax 2022-01-12 16:15:30 -08:00
Leonardo de Moura
49b2860f2a feat: add Meta.rename tactic 2022-01-12 16:15:30 -08:00
Leonardo de Moura
addcbc6fa3 feat: process termination_by syntax 2022-01-12 16:15:30 -08:00
Simon Hudon
6820c8bd92 feat: create lsp workspaces automatically 2022-01-12 19:26:55 +01:00
Leonardo de Moura
111d09fda3 fix: must apply afterCompilation attributes *after* smart unfolding definition was declared
The `[simp]` attribute checks whether the smart unfolding defintion
has been declared.

closes #946
2022-01-12 08:28:03 -08:00
Leonardo de Moura
45bd328d5e fix: tests and add WellFoundedRelation.rel to list of definitions to unfold at decreasing_tactic 2022-01-12 08:28:03 -08:00
Leonardo de Moura
e7eab602d9 fix: missing consumeAutoOptParam at addNewArg 2022-01-12 08:28:03 -08:00
Leonardo de Moura
7a86b613dc chore: remove old comment 2022-01-12 08:28:03 -08:00
Leonardo de Moura
a1ab5c0ccb feat: simplify termination_by new syntax
We don't need `using` anymore since we are going to use TC inference.
2022-01-12 08:28:03 -08:00
Leonardo de Moura
1a6abe1dad feat: WellFoundedRelation as a class 2022-01-12 08:28:03 -08:00
Gabriel Ebner
50abc3e295 fix: correctly pretty-print @Eq 2022-01-12 09:41:41 +01:00
Gabriel Ebner
bdc80ce50d fix: potential nontermination in delabFor 2022-01-12 09:41:41 +01:00
Gabriel Ebner
9132b27e80 fix: delabAppImplicit: strip mdata from function 2022-01-12 09:41:41 +01:00
Sebastian Ullrich
bcf61cc7bb chore: CI: remove ctest timeout, for now
Hopefully lsan will now have sufficient time to actually terminate
2022-01-12 10:24:45 +01:00
Leonardo de Moura
de19767594 feat: basic skeleton for termination_by' vs termination_by 2022-01-11 16:53:39 -08:00
Leonardo de Moura
4e5a51aa24 chore: fix test 2022-01-11 16:23:26 -08:00
Leonardo de Moura
868a43a747 chore: remove dead code 2022-01-11 16:22:20 -08:00
Leonardo de Moura
f9b79092f6 feat: new termination_by syntax 2022-01-11 15:36:50 -08:00
Leonardo de Moura
068cc700d8 test: ackermann 2022-01-11 15:03:07 -08:00
Leonardo de Moura
381f66428a chore: use termination_by'
We are going to define a higher level syntax for `termination_by`.
2022-01-11 15:00:53 -08:00
Leonardo de Moura
0434c36f89 chore: remove old version 2022-01-11 14:50:15 -08:00
Leonardo de Moura
4e47ef0cbb chore: update stage0 2022-01-11 14:48:42 -08:00
Leonardo de Moura
430b641e81 feat: use decreasing_tactic 2022-01-11 14:47:19 -08:00
Leonardo de Moura
74f732f4cb chore: update stage0 2022-01-11 14:45:16 -08:00
Leonardo de Moura
ce76ad44ea feat: add terminationByCore parser 2022-01-11 14:44:36 -08:00
Leonardo de Moura
ca89da28d0 chore: prepare to rename default_decreasing_tactic 2022-01-11 14:42:25 -08:00
Leonardo de Moura
2464da0dca feat: add support for PSigma.Lex at default_decreasing_tactic 2022-01-11 14:41:28 -08:00
Leonardo de Moura
a087b21bc0 fix: bug at WF/Fix.lean 2022-01-11 14:38:31 -08:00
Leonardo de Moura
ec49c31337 chore: make sure PSigma.lex signature is similar to Prod.lex 2022-01-11 14:37:53 -08:00
Leonardo de Moura
d953ac8d0d feat: allow users to use initialize registerBuiltinDerivingHandler ... 2022-01-11 09:50:09 -08:00
Leonardo de Moura
93f3773d83 chore: cleanup 2022-01-10 16:25:07 -08:00
Leonardo de Moura
dae3489fe2 feat: remove partials from Init/Data/Array/Basic.lean 2022-01-10 16:05:33 -08:00
Leonardo de Moura
a02421185c fix: add support for BinderInfo.auxDecl at delabLam 2022-01-10 15:18:49 -08:00
Leonardo de Moura
cee8ad1b66 chore: fix codebase 2022-01-10 15:07:55 -08:00
Leonardo de Moura
762b0f42ba chore: fix tests 2022-01-10 15:06:03 -08:00
Leonardo de Moura
a28ff92010 chore: update stage0 2022-01-10 15:05:47 -08:00
Leonardo de Moura
4c918a2363 feat: use default_decreasing_tactic at WF/Fix.lean 2022-01-10 14:55:38 -08:00
Leonardo de Moura
739ef7d166 fix: annotate let rec declarations as auxDecl
Reason:
1- Tactics such as `assumption` should ignore them.
2- We must annotate recursive applications with `mkRecAppWithSyntax`.
2022-01-10 14:35:05 -08:00
Leonardo de Moura
57b8912279 chore: fix tests 2022-01-10 14:33:02 -08:00
Leonardo de Moura
0dd3ce0598 chore: fix test 2022-01-10 14:31:23 -08:00
Leonardo de Moura
7789779020 feat: add simple default tactic for well-founded recursion 2022-01-10 14:26:08 -08:00
Leonardo de Moura
16b4aa81e5 chore: add helper lemmas for well-founded recursion 2022-01-10 14:07:35 -08:00
Leonardo de Moura
241db0fed6 chore: fix name 2022-01-10 13:20:49 -08:00
Leonardo de Moura
929aafa4c8 fix: generate an error if declaration name clashes with variable name
closes #799
2022-01-10 12:08:11 -08:00
Josh Levine
99f6469761 doc: fix typo (#935) 2022-01-10 10:26:24 -08:00
Sebastian Ullrich
bcd7185f42 chore: CI: try reenabling sanitized Lake test 2022-01-10 18:35:22 +01:00
Sebastian Ullrich
768df1581c chore: CI: put llvm-symbolizer in PATH for asan/lsan backtraces 2022-01-10 18:35:22 +01:00
Sebastian Ullrich
3acc21e128 chore: CI: try to make lsan terminate 2022-01-10 18:35:22 +01:00
Gabriel Ebner
dc65bb080a fix: race condition in RPC request handler 2022-01-10 13:37:40 +01:00
Sebastian Ullrich
60a70372af chore: remove stray file breaking stage 0 update
/cc @leodemoura
2022-01-10 12:57:51 +01:00
Josh Levine
1637d75d3f doc: fix trivial typo 2022-01-09 10:19:26 +01:00
Leonardo de Moura
b2d26380f2 fix: remove auxiliary discriminant let-declarations 2022-01-07 15:03:19 -08:00
Leonardo de Moura
1cf8467847 feat: add unfold conv tactic 2022-01-07 13:51:45 -08:00
Leonardo de Moura
49d0f3af52 test: unfold tactic 2022-01-07 13:51:45 -08:00
Leonardo de Moura
57b9e0852e fix: clear local context at mkUnfoldEq 2022-01-07 13:51:45 -08:00
Leonardo de Moura
b50e82bc93 feat: unfold tactic 2022-01-07 13:51:45 -08:00
Leonardo de Moura
c303bf6916 refactor: add helper methods for simp 2022-01-07 13:51:45 -08:00
Leonardo de Moura
b1b4705c14 feat: add unfold tactic parsers 2022-01-07 13:51:45 -08:00
Leonardo de Moura
e8a4dbbc2a chore: document and cleanup mkUnfoldProof 2022-01-07 13:51:45 -08:00
Leonardo de Moura
b797c982fc feat: add mkUnfoldProof 2022-01-07 13:51:45 -08:00
Gabriel Ebner
f146d456ce fix: only enable InsertReplaceEdit if supported 2022-01-07 20:28:10 +01:00
larsk21
8c2d7a35d3 fix: make set_option completion replace typed partial name 2022-01-07 17:06:26 +01:00
Mario Carneiro
dcaf3c615f fix: induction generalizing precedence 2022-01-07 10:45:45 +01:00
Leonardo de Moura
cc4c82a6e7 chore: update stage0 2022-01-06 17:44:42 -08:00
Leonardo de Moura
98f4e51a12 feat: add mkUnfoldEq skeleton 2022-01-06 17:42:45 -08:00
Leonardo de Moura
bef161caf7 feat: add better support for discharging equation theorem hypotheses 2022-01-06 14:42:23 -08:00
Andrei Cheremskoy
5eea97534f chore(doc): remove duplicate Tactics section (#927) 2022-01-06 14:03:15 -08:00
Leonardo de Moura
df6095e580 fix: casesOnStuckLHS method
It was not general enough.
2022-01-06 13:54:17 -08:00
Leonardo de Moura
90b179bea9 fix: add equation theorems even if definition supports smart unfolding
See new test.
2022-01-06 13:53:03 -08:00
Leonardo de Moura
d8d7d63830 fix: registers eqns info before adding definition
Otherwise `[simp]` at definition will fail to generate equational theorems.
2022-01-06 12:24:40 -08:00
Leonardo de Moura
7acbbb4fbb fix: auxiliary whnfAux used at mkEqns 2022-01-06 09:57:41 -08:00
Leonardo de Moura
60934bf1d5 feat: add support for removing [simp] attribute from definitions with equational theorems 2022-01-05 16:57:59 -08:00
Leonardo de Moura
c2e52bd577 feat: use getEqnsFor? when applying [simp] at definitions 2022-01-05 15:59:39 -08:00
Leonardo de Moura
ff49fd6b7e fix: apply afterCompilation attributes after we have compiled *all* definitions in a mutual block 2022-01-05 15:57:51 -08:00
Leonardo de Moura
030e932db8 feat: use getEqnsFor? at simp 2022-01-05 11:28:24 -08:00
Leonardo de Moura
4d1343d670 chore: use _eq instead of eq to name auto generated equational theorems 2022-01-04 17:23:34 -08:00
Leonardo de Moura
b2918e0c76 test: add tests for WF.mkEqns 2022-01-04 17:18:51 -08:00
Leonardo de Moura
d782a97f5c feat: add WF.mkProof for WF.mkEqns 2022-01-04 17:00:54 -08:00
Leonardo de Moura
2a0cd18d4b feat: add WF.mkEqns 2022-01-04 15:44:05 -08:00
Leonardo de Moura
fa597c6fb8 chore: update stage0 2022-01-04 15:32:33 -08:00
Leonardo de Moura
d941e97716 feat: add WF/Eqns.lean skeleton 2022-01-04 15:31:22 -08:00
Leonardo de Moura
947240ef9e refactor: add PreDefinition/Eqns.lean 2022-01-04 13:52:41 -08:00
ammkrn
f2cc9080a3 doc: document the split tactic 2022-01-04 13:28:36 -08:00
Mario Carneiro
5a7c9f2d35 chore: add showRhs definition 2022-01-04 09:28:29 -08:00
Leonardo de Moura
62d03fe8ad chore: update stage0 2022-01-04 09:27:33 -08:00
Mario Carneiro
9ee0d08cb5 chore: add doc 2022-01-04 09:26:34 -08:00
Mario Carneiro
3716e9a2ed chore: use a different syntax kind for suffices-by
chore: update src/Lean/Parser/Term.lean

Co-authored-by: Gabriel Ebner <gebner@gebner.org>
2022-01-04 09:26:32 -08:00
Gabriel Ebner
83e167dfb5 feat: append filename to worker command-line
This change has no effect on the server behavior.  The only difference
is that the filename now shows up in `htop`, `ps`, etc., which makes it much
easier to see what Lean processes are running, and which are using 100%
CPU, etc.
2022-01-04 15:10:46 +01:00
Sebastian Ullrich
64971a1e3c fix: term macro errors should be fatal 2022-01-04 11:20:18 +01:00
Leonardo de Moura
a000ee4249 chore: update stage0 2022-01-03 10:33:37 -08:00
Leonardo de Moura
b9f7d1defb fix: constant folding after erasure
closes #909
2022-01-03 10:33:07 -08:00
Leonardo de Moura
0e479d1f9f chore: use double ticks 2022-01-03 10:30:05 -08:00
Leonardo de Moura
bf17eec439 chore: update stage0 2022-01-03 09:37:18 -08:00
Leonardo de Moura
e9c112007b fix: avoid Syntax trees leaks into .olean files
closes #918
2022-01-03 09:36:06 -08:00
Leonardo de Moura
52b6a04088 test: for #916 2022-01-03 07:57:16 -08:00
Mario Carneiro
5e36162f9b fix: adapt to doHave syntax change 2022-01-03 07:55:52 -08:00
Mario Carneiro
3253231d59 feat: make rw [] syntactically correct 2022-01-03 07:23:24 -08:00
Leonardo de Moura
7dcc026cd1 chore: update stage0 2022-01-03 07:16:13 -08:00
Gabriel Ebner
bc5bd5a671 feat: allow the compiler to optimize unsafeCast 2022-01-03 07:13:55 -08:00
Gabriel Ebner
5cdaeac36f chore: update stage0 2022-01-03 07:13:55 -08:00
Gabriel Ebner
e605c541d0 fix: do not infer type in erase_irrelevant
At the time erase_irrelevant is called, we have already eliminated the
`cast`-applications.  Therefore non-atomic expressions may no longer
be well-typed (and `infer_type` can fail).
2022-01-03 07:13:55 -08:00
gabriel-doriath-dohler
6986032b38 doc: correct the link to "Lean Together 2021: Metaprogramming in Lean 4 continued" 2022-01-03 07:06:04 -08:00
Sebastian Ullrich
bbfcb1cfb2 perf: allocation-free for i in [n:m] do 2022-01-03 07:03:56 -08:00
Sebastian Ullrich
555584375a fix: compare fields top-down in deriving Ord 2022-01-03 07:02:13 -08:00
Sebastian Ullrich
132898f7e7 fix: reinstate monadic panic workaround 2022-01-03 14:58:24 +01:00
Henrik Böving
2d85c9ba2f chore: fix notation test
The ppNotationCode.lean test failed because the output of the notation
elaborator changed (purposely), adapt it to the new output.
2022-01-03 13:47:11 +01:00
Sebastian Ullrich
75233a40f7 chore: update stage0 2022-01-03 13:46:56 +01:00
Henrik Böving
4ee058039b chore: apply suggestions from code review
Co-authored-by: Gabriel Ebner <gebner@gebner.org>
2022-01-03 13:43:33 +01:00
Henrik Böving
5d3e3b9296 fix: don't drop tags in identNoAntiquot 2022-01-03 13:43:33 +01:00
Henrik Böving
6fe010d0c2 fix: keep info in auto generated notation delaborators
Previously automatically generated delaborators for syntax declared with
the notation (and derived) keywords would silently drop information
during delaboration.
2022-01-03 13:43:33 +01:00
Henrik Böving
cbedff5aba feat: optionally add information to all symbols during delaboration
Add an option called pp.tagSymbols which, if set, makes the
delaborator add term information to all symbols it can during
delaboration. This option is disabled per default because it would
break the LSP server's hovering behaviour. It is however useful
when for example automatically generating interactive documentation.
2022-01-03 13:43:33 +01:00
Mac
748c9ab73a chore: tweak error message
Co-authored-by: Wojciech Nawrocki <wjnawrocki+gh@protonmail.com>
2021-12-27 09:44:11 +01:00
tydeu
30bdd4e751 doc: add docstring for chainLspRequestHandler 2021-12-27 09:44:11 +01:00
tydeu
004e172f5d feat: LSP request handler chaining 2021-12-27 09:44:11 +01:00
Sebastian Ullrich
3da76efa10 chore: Nix: remove Leanpkg from default deps 2021-12-25 17:00:20 +01:00
Gabriel Ebner
70ef4e529c feat: allow attributes on structures and inductives 2021-12-23 08:04:36 -08:00
Gabriel Ebner
f43f74e78f chore: suppress newline after . 2021-12-23 13:56:22 +01:00
Gabriel Ebner
72851652f1 fix: spacing in suffices...by 2021-12-23 13:56:22 +01:00
Gabriel Ebner
25714a8ee1 fix: calc syntax roundtrip 2021-12-23 13:56:22 +01:00
Mario Carneiro
7956a9bb15 chore: typos 2021-12-23 10:14:39 +01:00
Sebastian Ullrich
292fb257a7 perf: do not specialize Prop typeclasses 2021-12-22 17:48:11 -08:00
Sebastian Ullrich
399ad64854 perf: do not specialize Inhabited 2021-12-22 17:48:11 -08:00
Sebastian Ullrich
45e8d9af43 feat: support [nospecialize] on typeclasses 2021-12-22 17:48:11 -08:00
Sebastian Ullrich
b4385bd259 perf: export lake symbols for the interpreter 2021-12-22 23:33:58 +01:00
Gabriel Ebner
546bb8f053 fix: widgets: do not highlight entire expression in popup 2021-12-21 21:54:51 +01:00
Sebastian Ullrich
fdd939fc40 fix: accidental memory leak in last commit 2021-12-21 19:43:02 +01:00
Sebastian Ullrich
3318f1fb05 feat: record declaration name in interpretation profile 2021-12-21 19:04:58 +01:00
Sebastian Ullrich
c62c8bd64b chore: reenable servertest_edit 2021-12-21 18:11:28 +01:00
Gabriel Ebner
412691c958 feat: support LEAN_NUM_THREADS environment variable 2021-12-21 17:01:08 +01:00
Sebastian Ullrich
5b653197db chore: use --run for servertests
/cc @Garmelon
2021-12-21 16:04:21 +01:00
Sebastian Ullrich
cbdad10419 chore: exclude flaky laketest under sanitizer for now
unclear how to reproduce
2021-12-21 12:19:22 +01:00
Sebastian Ullrich
b732484663 fix: do not consider worker threads as idle during startup
Without this change, enqueuing multiple tasks before the first worker
was started led to only a single worker being created. Now the first
increment and decrement happen under the task manager mutex, so
effectively the worker is never idle until it is out of tasks.
2021-12-21 12:01:23 +01:00
Leonardo de Moura
b278a20ac2 feat: ensure #eval converts unassigned universe metavars into parameters
see #898
2021-12-20 06:11:36 -08:00
Sebastian Ullrich
51dc32957b feat: show universe args on hover
We might also want to replace them with fresh vars to make the hover
completely independent of the context, but this change at least avoids
any hidden information.
2021-12-20 10:51:44 +01:00
Sebastian Ullrich
068ea1beb4 fix: leanc: do not change sysroot
Apparently clang is smart enough to look up runtime files missing from
the sysroot in the installation directory automatically.
2021-12-19 18:55:57 +01:00
Chris Lovett
c3a9860dc8 doc: replace leanpkg info with info about Lake
Fixes #789
2021-12-19 17:23:25 +01:00
Sebastian Ullrich
6f9c6e4556 doc: match: mention (generalizing := true) 2021-12-19 11:14:27 +01:00
Sebastian Ullrich
5f96a9fc4d fix: do not show type of sort in hover
Fixes #896
2021-12-19 11:03:15 +01:00
tydeu
f4a73889e7 feat: expose more version info (e..g., toolchain) 2021-12-19 10:44:35 +01:00
Leonardo de Moura
92a511be29 chore: fix test 2021-12-18 11:05:37 -08:00
Leonardo de Moura
6499798a35 chore: update stage0 2021-12-18 11:01:54 -08:00
Sebastian Ullrich
167dccce0b chore: move Leanpkg.leanVersionString to Init 2021-12-18 10:59:37 -08:00
Sebastian Ullrich
234d806f6b chore: deprecate leanpkg 2021-12-18 10:59:37 -08:00
Mario Carneiro
f17064809c fix doctest 2021-12-18 10:58:57 -08:00
Mario Carneiro
f22f699d62 feat: split replicate / replicateTR with @[csimp] 2021-12-18 10:58:57 -08:00
Leonardo de Moura
be6bc67eb0 fix: ensure match-expressions compiled using if-then-else can be reduced with TransparencyMode.reducible
closes #891
2021-12-18 10:55:42 -08:00
Leonardo de Moura
b3d8766b09 chore: use doubleticks at WHNF.lean 2021-12-18 08:43:50 -08:00
Leonardo de Moura
b6fbdd8679 feat: add Meta.Context.canUnfold? 2021-12-18 08:25:56 -08:00
Leonardo de Moura
c954fc9ec7 fix: bug at simpLoop 2021-12-18 06:48:08 -08:00
Sebastian Ullrich
cd94ec20b0 fix: aux_def: avoid creating unparseable names 2021-12-17 14:21:35 -08:00
Mario Carneiro
51a78fd7af fix: change argument order of List.get[!?D] 2021-12-17 14:21:00 -08:00
Mario Carneiro
caf09e85ad chore: universe generalize implies_true 2021-12-17 14:19:54 -08:00
Leonardo de Moura
d51def739e chore: update stage0 2021-12-17 07:25:59 -08:00
Leonardo de Moura
dce55f79ed feat: eliminate recursive application syntax annotation at addAndCompileUnsafe 2021-12-17 07:24:44 -08:00
Leonardo de Moura
7df9cf6a0a feat: eliminate "recAppSyntax" information during structural recursion 2021-12-17 07:15:14 -08:00
Leonardo de Moura
6b82e15069 feat: preserve variable names when packing domain 2021-12-17 07:10:26 -08:00
Leonardo de Moura
8b7411bdd8 feat: improve error location at well-founded recursion 2021-12-17 06:50:20 -08:00
Sebastian Ullrich
9e5ff3db0e feat: setMainModule in worker 2021-12-17 12:22:53 +01:00
Sebastian Ullrich
ca740f5687 chore: fix copy-produced 2021-12-17 12:22:53 +01:00
Sebastian Ullrich
51adfa2e0c fix: do not call lake print-paths for lakefile.lean
Fixes #873
2021-12-17 12:22:30 +01:00
tydeu
e34c892f89 chore: update Lake 2021-12-17 10:20:37 +01:00
Sebastian Ullrich
5a16745ad9 chore: Nix: add devShell 2021-12-17 09:43:22 +01:00
Leonardo de Moura
2d4d5ae96f feat: save syntax around recursive applications
Motivation: better error messages at structural and well-founded recursion.
2021-12-16 17:13:55 -08:00
Leonardo de Moura
e38fab1b4e fix: ignore Expr.MData at deltaRHS? 2021-12-16 16:58:10 -08:00
Leonardo de Moura
de29657594 feat: implement bool operator==(data_value const & a, data_value const & b) using Lean autogenerated code 2021-12-16 16:37:47 -08:00
Leonardo de Moura
dbe96a4434 chore: update stage0 2021-12-16 15:48:29 -08:00
Leonardo de Moura
867134614b feat: add constructor DataValue.ofSyntax 2021-12-16 15:41:29 -08:00
Gabriel Ebner
e65f3fe810 fix: use redirected stderr for tout() 2021-12-16 10:23:05 -08:00
Sebastian Ullrich
1221bdd3c7 fix: use redirected stderr for timeit & allocprof 2021-12-16 06:38:35 -08:00
Sebastian Ullrich
87e860f871 perf: Array.push: move elements directly when source is unique 2021-12-16 06:37:37 -08:00
tydeu
72cfe18e9f chore: update Lake 2021-12-16 11:10:33 +01:00
Joe Hendrix
5a307a93ac fix: bug at ByteArray.copySlice 2021-12-16 11:05:19 +01:00
Leonardo de Moura
fa8b015603 chore: update stage0 2021-12-15 17:09:39 -08:00
Leonardo de Moura
81f7335269 fix: ensure motive is type correct at simpProj 2021-12-15 17:07:31 -08:00
Leonardo de Moura
0a81093db5 fix: bug at simpProj
This bug was reported at https://github.com/dwrensha/lean4-maze/issues/1
2021-12-15 17:07:00 -08:00
Leonardo de Moura
9a24db4e86 fix: check generated motives at notation
This commit also improves the `▸` notation a bit.
It now tries `subst` (if applicable) before failing.
2021-12-15 16:16:42 -08:00
Leonardo de Moura
89edc184fb feat: compleation at #print command 2021-12-15 13:13:39 -08:00
Leonardo de Moura
653b684651 feat: improve getCompletionKindForDecl 2021-12-15 12:57:09 -08:00
Leonardo de Moura
7d7c6d8be5 feat: add CompletionItemKind 2021-12-15 11:24:11 -08:00
Leonardo de Moura
31f845c5ed feat: keyword completion 2021-12-15 11:24:11 -08:00
Leonardo de Moura
043e9c80b4 feat: add Trie.findPrefix 2021-12-15 11:24:11 -08:00
Sebastian Ullrich
ba83721109 chore: add comment for previous fix 2021-12-15 20:10:48 +01:00
Sebastian Ullrich
35e623fca0 chore: update stage0 2021-12-15 15:58:32 +01:00
Sebastian Ullrich
c8c39aa4bb chore: lean-gdb: fix RC printing 2021-12-15 15:58:31 +01:00
Sebastian Ullrich
3c9ea3b113 fix: wait on tasks before Lean program exit 2021-12-15 15:58:24 +01:00
larsk21
efa2ded224 chore: bump server version to 0.1.1 2021-12-15 13:00:05 +01:00
larsk21
d50c08360d feat: change error flag to progress kind in LeanFileProgressProcessingInfo 2021-12-15 13:00:05 +01:00
larsk21
dcbc526115 feat: report header processing errors as error progress 2021-12-15 13:00:05 +01:00
larsk21
925c530673 feat: add error field to LeanFileProgressProcessingInfo 2021-12-15 13:00:05 +01:00
Siddharth
37982c6d5c doc: structure update
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2021-12-15 11:48:46 +00:00
Gabriel Ebner
230d6d2cf5 fix: use group for if-then-else 2021-12-15 11:42:38 +00:00
Gabriel Ebner
202fd1414a chore: update stage0 2021-12-15 11:42:38 +00:00
Gabriel Ebner
d6f629860b feat: add ppRealFill and ppRealGroup combinators 2021-12-15 11:42:38 +00:00
Gabriel Ebner
b905824024 chore: fix tests 2021-12-15 11:42:38 +00:00
Gabriel Ebner
ab3e08190b feat: allow opt-out of grouping in formatter 2021-12-15 11:42:38 +00:00
Gabriel Ebner
b6efece612 fix: missing space after /-- 2021-12-15 11:42:38 +00:00
Gabriel Ebner
4f81972996 fix: missing newline before inductionAlt 2021-12-15 11:42:38 +00:00
Gabriel Ebner
f1fc8f2441 fix: space before where/:= in inductive 2021-12-15 11:42:38 +00:00
Gabriel Ebner
7be0d7ec16 fix: space before $ 2021-12-15 11:42:38 +00:00
Gabriel Ebner
3f73442a5a fix: space before infer modifiers 2021-12-15 11:42:38 +00:00
Gabriel Ebner
b176efefca fix: print line before deriving 2021-12-15 11:42:38 +00:00
Gabriel Ebner
5d25df1a69 fix: indenting of match arms in declValEqns 2021-12-15 11:42:38 +00:00
Gabriel Ebner
067c181075 fix: space after @& 2021-12-15 11:42:38 +00:00
Gabriel Ebner
e1b2c945e3 fix: suppress extra spaces in formatter 2021-12-15 11:42:38 +00:00
Gabriel Ebner
2b7ec7f9ef fix: spacing around (← monadic lifts) 2021-12-15 11:42:38 +00:00
Gabriel Ebner
52b36cad1d fix: whitespace around parens in open/export 2021-12-15 11:42:38 +00:00
Gabriel Ebner
87faa7a93a fix: whitespace after rw/simp [<- 2021-12-15 11:42:38 +00:00
Gabriel Ebner
f219188c95 fix: indent declaration signatures 2021-12-15 11:42:38 +00:00
Gabriel Ebner
e90bdd00db fix: indent where definitions and add space before 2021-12-15 11:42:38 +00:00
Gabriel Ebner
f5a2562575 fix: indent structure fields 2021-12-15 11:42:38 +00:00
Gabriel Ebner
316fa81042 fix: print spaces around <| and |> 2021-12-15 11:42:38 +00:00
Gabriel Ebner
f1d583c9cf fix: newline in whereDecls 2021-12-15 11:42:38 +00:00
Gabriel Ebner
448d2cd951 feat: add script to reformat lean files 2021-12-15 11:42:38 +00:00
Gabriel Ebner
7e483d3a0a feat: support syntax abbreviations in dynamic quotations 2021-12-15 11:17:58 +00:00
tydeu
a3250dc44b feat: expose --load-dynlib functionality to Lean code 2021-12-15 08:26:48 +00:00
Leonardo de Moura
34430cd7c3 fix: semantic highlighting for keywords of the form #<alpha>...
closes #703
2021-12-14 17:58:56 -08:00
Leonardo de Moura
5b14caf329 fix: missing addTermInfo at elabAtomicDiscr
closes #820
2021-12-14 17:20:46 -08:00
tydeu
42d8c333a6 chore: update Lake 2021-12-14 14:36:21 -08:00
Gabriel Ebner
45bcef5dab refactor: server: use String.firstDiffPos to find changes
This is necessary so that we do not reprocess the whole file if
incremental sync is disabled.
2021-12-14 11:55:34 -08:00
tydeu
c0693c93be chore: update Lake 2021-12-14 11:53:51 -08:00
Leonardo de Moura
448bac5b3e chore: one add_test per lake test 2021-12-14 11:48:14 -08:00
Leonardo de Moura
136fab0723 feat: improve error message for let ... ← ... outside of a do 2021-12-14 08:56:22 -08:00
Leonardo de Moura
1c83ea9e40 fix: typo at hasUnusedArguments
See comment at #815
2021-12-14 06:50:34 -08:00
tydeu
26a225e230 chore: fix tests 2021-12-14 09:33:52 +01:00
tydeu
d518ba7f08 feat: use BaseIO more in Init.System.IO 2021-12-14 09:33:52 +01:00
Leonardo de Moura
3856d0030c feat: improve do notation error message for pure code
See #770
2021-12-13 11:08:38 -08:00
Leonardo de Moura
e335b2ac8a feat: add noncomputable sections
See https://github.com/leanprover-community/mathport/issues/71
2021-12-13 11:02:46 -08:00
Leonardo de Moura
5f0def2edf chore: update stage0 2021-12-13 10:39:19 -08:00
Leonardo de Moura
55db56f80d feat: add noncomputable section parser 2021-12-13 10:35:16 -08:00
Sebastian Ullrich
0ade9ee39b fix: make IO.Process.Child.wait fallible 2021-12-13 15:12:48 +01:00
Leonardo de Moura
3a6cc77424 chore: update lake 2021-12-12 08:29:30 -08:00
Leonardo de Moura
133c58aba2 chore: update stage0 2021-12-12 08:17:30 -08:00
Leonardo de Moura
bf3b0c53ad chore: add helper parser 2021-12-12 08:16:42 -08:00
Leonardo de Moura
b2e065a3ba chore: avoid where structure instance notation
This is a workaround to avoid staging issues.
2021-12-12 07:59:38 -08:00
Leonardo de Moura
b6ef65d8fd fix: where structure instance parser
closes #753
2021-12-12 07:52:52 -08:00
Leonardo de Moura
a3361e7d86 fix: missing universe assignments made during TC resolution
closes #796
2021-12-12 07:07:13 -08:00
Sebastian Ullrich
a91b861919 Revert "chore: CI: propagate prepare-*.sh errors"
This reverts commit 198d3103cd.
2021-12-11 17:37:12 +01:00
Sebastian Ullrich
198d3103cd chore: CI: propagate prepare-*.sh errors 2021-12-11 09:51:27 +01:00
Sebastian Ullrich
ed3dad9313 fix: bundling on Linux 2021-12-11 09:10:06 +01:00
tydeu
d785652792 chore: update Lake 2021-12-10 16:38:31 -08:00
Leonardo de Moura
d5f1a5d1d1 fix: in-word completion
closes #857
2021-12-10 15:48:35 -08:00
Sebastian Ullrich
fddbc3c09e fix: empty option completion 2021-12-10 14:19:19 -08:00
Sebastian Ullrich
a4633d30e2 fix: option completion after trailing . 2021-12-10 14:19:19 -08:00
Sebastian Ullrich
74dba7c64e fix: do not hide trace messages on partial syntax 2021-12-10 14:19:19 -08:00
Sebastian Ullrich
ce2e733f17 fix: make option completion work in presence of value 2021-12-10 14:19:19 -08:00
Leonardo de Moura
1003840376 chore: update lake 2021-12-10 13:20:27 -08:00
Leonardo de Moura
63decd445c chore: fix test 2021-12-10 13:13:03 -08:00
Leonardo de Moura
68bd55af32 chore: fix codebase 2021-12-10 13:12:09 -08:00
Leonardo de Moura
d9d44baabe chore: update stage0 2021-12-10 12:56:00 -08:00
Leonardo de Moura
483f32edd8 feat: in pure code, do use assume Id monad at do notation
This feature produced counterintuitive behavior and confused users.
See discussion at #770.

As pointed out by @tydeu, it is not too much work to write `Id.run <|`
before the `do` when we want to use the `do` notation in pure code.

closes #770
2021-12-10 12:55:14 -08:00
Leonardo de Moura
96e0e1db98 fix: nontermination at simp [OfNat.ofNat]
closes #788
2021-12-10 12:29:33 -08:00
Leonardo de Moura
47c2d335d4 fix: completion for aliases
closes #863
2021-12-10 12:14:11 -08:00
Leonardo de Moura
84f374702d feat: add fields isInstance and isType to InteractiveHypothesis
see https://github.com/leanprover/vscode-lean4/issues/76
2021-12-10 09:08:55 -08:00
Sebastian Ullrich
5796bb835c fix: Nix: shell.nix on macOS 2021-12-10 16:13:45 +01:00
Joscha
d19cfede02 fix: implement suggestions 2021-12-10 15:25:43 +01:00
Joscha
e4406f1785 fix: find references to function parameters in function body
With #861, the server can now connect the occurrences of parameters in the
function definition and in the function body to each other.
2021-12-10 15:25:43 +01:00
Joscha
12ee541622 fix: reference fields in constructor correctly 2021-12-10 15:25:43 +01:00
Joscha
11ba6dc216 test: add simple "find references" test 2021-12-10 15:25:43 +01:00
Joscha
2823cbc87b feat: implement single-file "find references" in LSP server 2021-12-10 15:25:43 +01:00
Leonardo de Moura
e64cfbb9b2 test: well-founded recursion example
see #860
2021-12-09 14:32:06 -08:00
Leonardo de Moura
45f5909dd0 chore: register Elab.resume trace class 2021-12-09 13:37:39 -08:00
Sebastian Ullrich
77aed3a0b1 fix: add binder info nodes for parameter copies in body 2021-12-09 18:12:51 +01:00
2553 changed files with 46627 additions and 24575 deletions

2
.gitattributes vendored
View File

@@ -1,3 +1,3 @@
*.expected.out -text
doc/changes.md merge=union
RELEASES.md merge=union
stage0/** binary linguist-generated

View File

@@ -9,12 +9,35 @@ on:
branches:
- master
schedule:
- cron: '0 0 * * *'
- cron: '0 7 * * *' # 8AM CET/11PM PT
jobs:
Build:
set-nightly:
# don't schedule nightlies on forks
if: github.event_name != 'schedule' || github.repository == 'leanprover/lean4'
if: github.event_name == 'schedule' && github.repository == 'leanprover/lean4'
runs-on: ubuntu-latest
outputs:
nightly: ${{ steps.set.outputs.nightly }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set Nightly
id: set
run: |
if [[ -n '${{ secrets.PUSH_NIGHTLY_TOKEN }}' ]]; then
git remote add nightly https://foo:'${{ secrets.PUSH_NIGHTLY_TOKEN }}'@github.com/${{ github.repository_owner }}/lean4-nightly.git
git fetch nightly --tags
LEAN_VERSION_STRING="nightly-$(date -u +%F)"
# do nothing if commit already has a different tag
if [[ $(git name-rev --name-only --tags --no-undefined HEAD 2> /dev/null || echo $LEAN_VERSION_STRING) == $LEAN_VERSION_STRING ]]; then
echo "::set-output name=nightly::$LEAN_VERSION_STRING"
fi
fi
build:
needs: set-nightly
# `always` *must* be used to continue even after a dependency has been skipped
if: always() && (github.event_name != 'schedule' || github.repository == 'leanprover/lean4')
runs-on: ${{ matrix.os }}
defaults:
run:
@@ -27,9 +50,11 @@ jobs:
os: ubuntu-latest
release: true
shell: nix-shell --arg pkgsDist "import (fetchTarball \"channel:nixos-19.03\") {{}}" --run "bash -euxo pipefail {0}"
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/13.0.0/lean-llvm-x86_64-linux-gnu.tar.zst
prepare-llvm: script/prepare-llvm-linux.sh lean-llvm*
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/14.0.0/lean-llvm-x86_64-linux-gnu.tar.zst
prepare-llvm: ../script/prepare-llvm-linux.sh lean-llvm*
binary-check: ldd -v
# foreign code may be linked against more recent glibc
CTEST_OPTIONS: -E 'foreign|leanlaketest_git'
- name: Linux
os: ubuntu-latest
check-stage3: true
@@ -41,13 +66,24 @@ jobs:
os: ubuntu-latest
# turn off custom allocator & symbolic functions to make LSAN do its magic
CMAKE_OPTIONS: -DLEAN_EXTRA_CXX_FLAGS=-fsanitize=address,undefined -DLEANC_EXTRA_FLAGS='-fsanitize=address,undefined -fsanitize-link-c++-runtime' -DSMALL_ALLOCATOR=OFF -DBSYMBOLIC=OFF
# exclude problematic tests
CTEST_OPTIONS: -E laketest
- name: macOS
os: macos-latest
release: true
shell: bash -euxo pipefail {0}
CMAKE_OPTIONS: -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/13.0.0/lean-llvm-x86_64-apple-darwin.tar.zst
prepare-llvm: script/prepare-llvm-macos.sh lean-llvm*
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/14.0.0/lean-llvm-x86_64-apple-darwin.tar.zst
prepare-llvm: ../script/prepare-llvm-macos.sh lean-llvm*
binary-check: otool -L
- name: macOS aarch64
os: macos-latest
release: true
cross: true
shell: bash -euxo pipefail {0}
CMAKE_OPTIONS: -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DUSE_GMP=OFF -DLEAN_INSTALL_SUFFIX=-darwin_aarch64
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/14.0.0/lean-llvm-aarch64-apple-darwin.tar.zst https://github.com/leanprover/lean-llvm/releases/download/14.0.0/lean-llvm-x86_64-apple-darwin.tar.zst
prepare-llvm: EXTRA_FLAGS=--target=aarch64-apple-darwin ../script/prepare-llvm-macos.sh lean-llvm-aarch64-* lean-llvm-x86_64-*
binary-check: otool -L
- name: Windows
os: windows-2022
@@ -56,9 +92,17 @@ jobs:
CMAKE_OPTIONS: -G "Unix Makefiles"
# for reasons unknown, interactivetests are flaky on Windows
CTEST_OPTIONS: --repeat until-pass:2
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/13.0.0/lean-llvm-x86_64-w64-windows-gnu.tar.zst
prepare-llvm: script/prepare-llvm-mingw.sh lean-llvm*
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/14.0.0/lean-llvm-x86_64-w64-windows-gnu.tar.zst
prepare-llvm: ../script/prepare-llvm-mingw.sh lean-llvm*
binary-check: ldd
- name: Linux aarch64
os: ubuntu-latest
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=$GMP -DLEAN_INSTALL_SUFFIX=-linux_aarch64
release: true
cross: true
shell: nix-shell --arg pkgsDist "import (fetchTarball \"channel:nixos-19.03\") {{ localSystem.config = \"aarch64-unknown-linux-gnu\"; }}" --run "bash -euxo pipefail {0}"
llvm-url: https://github.com/leanprover/lean-llvm/releases/download/14.0.0/lean-llvm-x86_64-linux-gnu.tar.zst https://github.com/leanprover/lean-llvm/releases/download/14.0.0/lean-llvm-aarch64-linux-gnu.tar.zst
prepare-llvm: EXTRA_FLAGS=--target=aarch64-unknown-linux-gnu ../script/prepare-llvm-linux.sh lean-llvm-aarch64-* lean-llvm-x86_64-*
# complete all jobs
fail-fast: false
name: ${{ matrix.name }}
@@ -70,12 +114,13 @@ jobs:
CCACHE_MAXSIZE: 200M
# squelch error message about missing nixpkgs channel
NIX_BUILD_SHELL: bash
LSAN_OPTIONS: max_leaks=10
# somehow MinGW clang64 (or cmake?) defaults to `g++` even though it doesn't exist
CXX: c++
steps:
- name: Checkout
uses: actions/checkout@v2
with:
# interferes with lean4-nightly authentication
persist-credentials: false
submodules: true
- name: Install Nix
uses: cachix/install-nix-action@v15
@@ -84,7 +129,8 @@ jobs:
uses: msys2/setup-msys2@v2
with:
msystem: clang64
install: make python mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-ccache git zip unzip diffutils binutils tree mingw-w64-clang-x86_64-zstd tar
# `:p` means prefix with appropriate msystem prefix
pacboy: "make python cmake:p clang:p ccache:p gmp:p git zip unzip diffutils binutils tree zstd:p tar"
if: matrix.os == 'windows-2022'
- name: Install Brew Packages
run: |
@@ -94,35 +140,27 @@ jobs:
uses: actions/cache@v2
with:
path: .ccache
key: ${{ matrix.name }}-build-${{ github.sha }}
key: ${{ matrix.name }}-build-v3-${{ github.sha }}
# fall back to (latest) previous cache
restore-keys: |
${{ matrix.name }}-build
${{ matrix.name }}-build-v3
- name: Setup
run: |
# open nix-shell once for initial setup
true
if: matrix.os == 'ubuntu-latest'
# remove problematic tests for sanitized build
- name: Pre build
run: rm tests/compiler/StackOverflow.lean tests/compiler/StackOverflowTask.lean
if: matrix.name == 'Linux fsanitize'
- name: Build
run: |
mkdir build
cd build
OPTIONS=()
[[ -z '${{ matrix.llvm-url }}' ]] || wget -q ${{ matrix.llvm-url }}
[[ -z '${{ matrix.prepare-llvm }}' ]] || eval "OPTIONS+=($(../${{ matrix.prepare-llvm }}))"
if [[ $GITHUB_EVENT_NAME == 'schedule' && -n '${{ matrix.release }}' && -n '${{ secrets.PUSH_NIGHTLY_TOKEN }}' ]]; then
git remote add nightly https://foo:'${{ secrets.PUSH_NIGHTLY_TOKEN }}'@github.com/${{ github.repository_owner }}/lean4-nightly.git
git fetch nightly --tags
LEAN_VERSION_STRING="nightly-$(date -u +%F)"
# do nothing if commit already has a different tag
if [[ $(git name-rev --name-only --tags --no-undefined HEAD 2> /dev/null || echo $LEAN_VERSION_STRING) == $LEAN_VERSION_STRING ]]; then
OPTIONS+=(-DLEAN_SPECIAL_VERSION_DESC=$LEAN_VERSION_STRING)
echo "LEAN_VERSION_STRING=$LEAN_VERSION_STRING" >> $GITHUB_ENV
fi
if [[ -n '${{ matrix.prepare-llvm }}' ]]; then
wget -q ${{ matrix.llvm-url }}
PREPARE="$(${{ matrix.prepare-llvm }})"
eval "OPTIONS+=($PREPARE)"
fi
if [[ -n '${{ matrix.release }}' && -n '${{ needs.set-nightly.outputs.nightly }}' ]]; then
OPTIONS+=(-DLEAN_SPECIAL_VERSION_DESC=${{ needs.set-nightly.outputs.nightly }})
fi
# contortion to support empty OPTIONS with old macOS bash
cmake .. ${{ matrix.CMAKE_OPTIONS }} ${OPTIONS[@]+"${OPTIONS[@]}"} -DLEAN_INSTALL_PREFIX=$PWD/..
@@ -139,25 +177,34 @@ jobs:
dir=$(echo lean-*)
mkdir pack
# high-compression tar.zst + zip for release, fast tar.zst otherwise
if [[ ${{ startsWith(github.ref, 'refs/tags/v') && matrix.release }} == true || -n ${LEAN_VERSION_STRING:-} ]]; then
if [[ '${{ startsWith(github.ref, 'refs/tags/v') && matrix.release }}' == true || -n '${{ needs.set-nightly.outputs.nightly }}' ]]; then
tar cf - $dir | zstd -T0 --no-progress -19 -o pack/$dir.tar.zst
zip -r pack/$dir.zip $dir
zip -rq pack/$dir.zip $dir
else
tar cf - $dir | zstd -T0 --no-progress -o pack/$dir.tar.zst
fi
- uses: actions/upload-artifact@v2
if: matrix.release
with:
name: build-${{ matrix.name }}
path: pack/*.zst
path: pack/*
- name: Trigger TPIL build
run: |
curl -u '${{ github.repository_owner }}:${{ secrets.PUSH_NIGHTLY_TOKEN }}' 'https://api.github.com/repos/leanprover/theorem_proving_in_lean4/dispatches' -X POST -d '{ "event_type": "build_event" }'
if: matrix.name == 'Linux release' && github.event_name == 'push' && github.repository == 'leanprover/lean4'
- name: Lean stats
run: |
build/stage1/bin/lean --stats src/Lean.lean
if: ${{ !matrix.cross }}
- name: Test
run: |
cd build/stage1
ctest -j4 --output-on-failure --timeout 300 ${{ matrix.CTEST_OPTIONS }} < /dev/null
# exclude nonreproducible test
ctest -j4 --output-on-failure -E leanlaketest_git ${{ matrix.CTEST_OPTIONS }} < /dev/null
if: ${{ !matrix.cross }}
- name: Check Test Binary
run: ${{ matrix.binary-check }} tests/compiler/534.lean.out
if: ${{ !matrix.cross }}
- name: Build Stage 2
run: |
cd build
@@ -172,7 +219,8 @@ jobs:
run: |
echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
export BUILD=$PWD/build PATH=$PWD/build/stage1/bin:$PATH
nix-shell -A with-temci --run "cd tests/bench; temci exec --config speedcenter.yaml --included_blocks fast --runs 1"
cd tests/bench
nix shell .#temci -c temci exec --config speedcenter.yaml --included_blocks fast --runs 1
if: matrix.test-speedcenter
- name: Check rebootstrap
run: |
@@ -181,40 +229,62 @@ jobs:
if: matrix.name == 'Linux'
- name: CCache stats
run: ccache -s
release:
# When GitHub says "If a job fails, all jobs that need it are skipped unless
# the jobs use a conditional expression that causes the job to continue.", don't believe
# their lies. It's actually the entire closure (i.e. including `set-nightly`) that
# must succeed for subsequent to be run without `always()`.
if: always() && needs.build.result == 'success' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/download-artifact@v2
with:
path: artifacts
- name: Release
uses: softprops/action-gh-release@v1
if: ${{ startsWith(github.ref, 'refs/tags/v') && matrix.release }}
with:
files: pack/*
files: artifacts/*/*
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
release-nightly:
needs: [set-nightly, build]
if: needs.set-nightly.outputs.nightly
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
# needed for tagging
fetch-depth: 0
token: ${{ secrets.PUSH_NIGHTLY_TOKEN }}
- uses: actions/download-artifact@v2
with:
path: artifacts
- name: Prepare Nightly Release
if: env.LEAN_VERSION_STRING
run: |
# can't push shallow checkout
git fetch --unshallow
git remote add nightly https://foo:'${{ secrets.PUSH_NIGHTLY_TOKEN }}'@github.com/${{ github.repository_owner }}/lean4-nightly.git
git fetch nightly --tags
if git tag $LEAN_VERSION_STRING && git push nightly $LEAN_VERSION_STRING; then
last_tag=$(git describe HEAD^ --abbrev=0 --tags)
echo -e "Changes since ${last_tag}:\n\n" > diff.md
#git show $last_tag:doc/changes.md > old.md
#./script/diff_changelogs.py old.md doc/changes.md >> diff.md
echo -e "*Full commit log*\n" >> diff.md
git log --oneline $last_tag..HEAD | sed 's/^/* /' >> diff.md
else
# make sure every runner is building the same commit
[ $(git rev-parse HEAD) == $(git rev-parse $LEAN_VERSION_STRING) ] || exit 11
echo -n > diff.md
fi
git tag ${{ needs.set-nightly.outputs.nightly }}
git push nightly ${{ needs.set-nightly.outputs.nightly }}
last_tag=$(git describe HEAD^ --abbrev=0 --tags)
echo -e "*Changes since ${last_tag}:*\n\n" > diff.md
git show $last_tag:RELEASES.md > old.md
#./script/diff_changelogs.py old.md doc/changes.md >> diff.md
diff --changed-group-format='%>' --unchanged-group-format='' old.md RELEASES.md >> diff.md || true
echo -e "\n*Full commit log*\n" >> diff.md
git log --oneline $last_tag..HEAD | sed 's/^/* /' >> diff.md
- name: Release Nightly
# need unreleased version for fixed `repository`
uses: Kha/action-gh-release@master
if: env.LEAN_VERSION_STRING
uses: softprops/action-gh-release@v1
with:
body_path: diff.md
prerelease: true
files: pack/*
tag_name: ${{ env.LEAN_VERSION_STRING }}
files: artifacts/*/*
fail_on_unmatched_files: true
tag_name: ${{ needs.set-nightly.outputs.nightly }}
repository: ${{ github.repository_owner }}/lean4-nightly
env:
GITHUB_TOKEN: ${{ secrets.PUSH_NIGHTLY_TOKEN }}

View File

@@ -14,18 +14,14 @@ jobs:
runs-on: ${{ matrix.os }}
defaults:
run:
# Can't use `nix-shell` without configured nixpkgs path on macOS
shell: nix -v --experimental-features "nix-command flakes" run .#ciShell -- bash -euxo pipefail {0}
strategy:
matrix:
include:
- name: Linux
- name: Nix Linux
os: ubuntu-latest
# latest builds on https://hydra.nixos.org/jobset/nix/master/all at the time
nix_url: https://hydra.nixos.org/build/135773533/download/1/nix-2.4pre20210125_36c4d6f-x86_64-linux.tar.xz
#- name: macOS
# os: macos-latest
# nix_url: https://hydra.nixos.org/build/135773542/download/1/nix-2.4pre20210125_36c4d6f-x86_64-darwin.tar.xz
- name: Nix macOS
os: macos-latest
# complete all jobs
fail-fast: false
name: ${{ matrix.name }}
@@ -34,39 +30,30 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
# Install flakes-enabled Nix manually from Hydra since `install-nix-action` doesn't accept raw tarballs
- name: Install Nix
shell: bash -euo pipefail {0}
run: |
curl ${{ matrix.nix_url }} | tar -xJ
# Do a single-user install so actions/cache doesn't get confused about permissions
nix-*/install --no-daemon --no-channel-add --darwin-use-unencrypted-nix-store-volume
rm -rf nix-*
# Call `install-nix-action` anyways to run its Actions-specific setup
- name: Setup Nix
uses: cachix/install-nix-action@v12
- name: Fixup install-nix-action
shell: bash -euo pipefail {0}
run: |
# the path set by install-nix-action is valid only for multi-user installations
echo "NIX_SSL_CERT_FILE=$HOME/.nix-profile/etc/ssl/certs/ca-bundle.crt" > $GITHUB_ENV
if: matrix.name == 'macOS'
- name: Further setup Nix
run: |
mkdir -p ~/.config/nix
echo '
max-jobs = auto
uses: cachix/install-nix-action@v15
with:
extra_nix_config: |
extra-sandbox-paths = /nix/var/cache/ccache
extra-substituters = file://${{ github.workspace }}/nix-store-cache?priority=10&trusted=true
extra-trusted-substituters = https://lean4.cachix.org/
extra-trusted-public-keys = lean4.cachix.org-1:mawtxSxcaiWE24xCXXgh3qnvlTkyU7evRRnGeAhD4Wk=' > ~/.config/nix/nix.conf
substituters = file://${{ github.workspace }}/nix-store-cache-copy?priority=10&trusted=true https://cache.nixos.org
- name: Set Up Nix Cache
uses: actions/cache@v2
with:
path: nix-store-cache
key: ${{ matrix.name }}-nix-store-cache-${{ github.sha }}
# fall back to (latest) previous cache
restore-keys: |
${{ matrix.name }}-nix-store-cache
- name: Further Set Up Nix Cache
shell: bash -euxo pipefail {0}
run: |
# Nix seems to mutate the cache, so make a copy
cp -r nix-store-cache nix-store-cache-copy || true
- name: Prepare CCache Cache
shell: bash -euxo pipefail {0}
run: |
sudo mkdir -m0770 -p /nix/var/cache/ccache
# macOS standard chown doesn't support --reference
nix shell .#nixpkgs.coreutils -c sudo chown --reference=/nix /nix/var/cache/ccache
echo 'max_size = 50M' > /nix/var/cache/ccache/ccache.conf
# install & use Cachix manually since `cachix-action` pushes *all* derivations (incl. `$mod-deps`, stage 2&3, etc.)
[ -z '${{ secrets.CACHIX_AUTH_TOKEN }}' ] || nix-env -iA cachix -f https://cachix.org/api/v1/install
sudo chown -R $USER /nix/var/cache/ccache
- name: Setup CCache Cache
uses: actions/cache@v2
with:
@@ -75,31 +62,33 @@ jobs:
# fall back to (latest) previous cache
restore-keys: |
${{ matrix.name }}-nix-ccache
- name: Setup Nix Cache
uses: actions/cache@v2
- name: Further Set Up CCache Cache
shell: bash -euxo pipefail {0}
run: |
sudo chown -R root:nixbld /nix/var/cache
sudo chmod -R 770 /nix/var/cache
- name: Install Cachix
uses: cachix/cachix-action@v10
with:
path: nix-store-cache
key: ${{ matrix.name }}-nix-store-cache-${{ github.sha }}
# fall back to (latest) previous cache
restore-keys: |
${{ matrix.name }}-nix-store-cache
name: lean4
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
skipPush: true # we push specific outputs only
- name: Build
run: |
# .o files are not a runtime dependency on macOS because of lack of thin archives
nix build $NIX_BUILD_ARGS .#stage0 .#stage1.lean-all .#Lean.oTree -o push-build
# leanc_src is required for building Leanc-deps
nix build $NIX_BUILD_ARGS .#stage0 .#stage1.lean-all .#lean-bin-tools-unwrapped.leanc_src .#Lean.oTree .#iTree -o push-build
- name: Test
run: |
nix build $NIX_BUILD_ARGS .#test -o push-test
- name: Build manual
run: |
nix build $NIX_BUILD_ARGS .#mdbook .#doc-test -o push-doc
nix build $NIX_BUILD_ARGS .#doc
if: matrix.name == 'Linux'
nix build $NIX_BUILD_ARGS --update-input lean --no-write-lock-file ./doc#{lean-mdbook,leanInk,alectryon,test} -o push-doc
nix build $NIX_BUILD_ARGS --update-input lean --no-write-lock-file ./doc
if: matrix.name == 'Nix Linux'
- name: Push to Cachix
run: |
[ -z "$CACHIX_AUTH_TOKEN" ] || cachix push -j4 lean4 ./push-* || true
env:
CACHIX_AUTH_TOKEN: '${{ secrets.CACHIX_AUTH_TOKEN }}'
[ -z "${{ secrets.CACHIX_AUTH_TOKEN }}" ] || cachix push -j4 lean4 ./push-* || true
- name: Rebuild Nix Store Cache
run: |
rm -rf nix-store-cache || true
@@ -110,6 +99,9 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./result
destination_dir: ./doc
if: matrix.name == 'Linux' && github.ref == 'refs/heads/master' && github.event_name == 'push'
if: matrix.name == 'Nix Linux' && github.ref == 'refs/heads/master' && github.event_name == 'push'
- name: Fixup CCache Cache
run: |
sudo chown -R $USER /nix/var/cache/ccache
- name: CCache stats
run: CCACHE_DIR=/nix/var/cache/ccache nix run .#nixpkgs.ccache -- -s

1
.ignore Normal file
View File

@@ -0,0 +1 @@
stage0/

View File

@@ -3,9 +3,13 @@ This is the repository for **Lean 4**, which is currently being released as mile
# About
- [Quickstart](https://github.com/leanprover/lean4/blob/master/doc/quickstart.md)
- [Homepage](https://leanprover.github.io)
- [Theorem Proving Tutorial](https://leanprover.github.io/theorem_proving_in_lean4/)
- [Functional Programming in Lean](https://leanprover.github.io/functional_programming_in_lean/) **first chapter is available!**
- [Manual](https://leanprover.github.io/lean4/doc/)
- [Release notes](RELEASES.md) starting at v4.0.0-m3
- [Examples](https://leanprover.github.io/lean4/doc/examples.html)
- [FAQ](https://leanprover.github.io/lean4/doc/faq.html)
# Installation

745
RELEASES.md Normal file
View File

@@ -0,0 +1,745 @@
Unreleased
---------
* Try to elaborate `do` notation even if the expected type is not available. We still delay elaboration when the expected type
is not available. This change is particularly useful when writing examples such as
```lean
#eval do
IO.println "hello"
IO.println "world"
```
That is, we don't have to use the idiom `#eval show IO _ from do ...` anymore.
Note that auto monadic lifting is less effective when the expected type is not available.
Monadic polymorphic functions (e.g., `ST.Ref.get`) also require the expected type.
* On Linux, panics now print a backtrace by default, which can be disabled by setting the environment variable `LEAN_BACKTRACE` to `0`.
Other platforms are TBD.
* The `group(·)` `syntax` combinator is now introduced automatically where necessary, such as when using multiple parsers inside `(...)+`.
* Add ["Typed Macros"](https://github.com/leanprover/lean4/pull/1251): syntax trees produced and accepted by syntax antiquotations now remember their syntax kinds, preventing accidental production of ill-formed syntax trees and reducing the need for explicit `:kind` antiquotation annotations. See PR for details.
* Aliases of protected definitions are protected too. Example:
```lean
protected def Nat.double (x : Nat) := 2*x
namespace Ex
export Nat (double) -- Add alias Ex.double for Nat.double
end Ex
open Ex
#check Ex.double -- Ok
#check double -- Error, `Ex.double` is alias for `Nat.double` which is protected
```
* Use `IO.getRandomBytes` to initialize random seed for `IO.rand`. See discussion at [this PR](https://github.com/leanprover/lean4-samples/pull/2).
* Improve dot notation and aliases interaction. See discussion on [Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Namespace-based.20overloading.20does.20not.20find.20exports/near/282946185) for additional details.
Example:
```lean
def Set (α : Type) := α → Prop
def Set.union (s₁ s₂ : Set α) : Set α := fun a => s₁ a s₂ a
def FinSet (n : Nat) := Fin n → Prop
namespace FinSet
export Set (union) -- FinSet.union is now an alias for `Set.union`
end FinSet
example (x y : FinSet 10) : FinSet 10 :=
x.union y -- Works
```
* `ext` and `enter` conv tactics can now go inside let-declarations. Example:
```lean
example (g : Nat → Nat) (y : Nat) (h : let x := y + 1; g (0+x) = x) : g (y + 1) = y + 1 := by
conv at h => enter [x, 1, 1]; rw [Nat.zero_add]
/-
g : Nat → Nat
y : Nat
h : let x := y + 1;
g x = x
⊢ g (y + 1) = y + 1
-/
exact h
```
* Add `zeta` conv tactic to expand let-declarations. Example:
```lean
example (h : let x := y + 1; 0 + x = y) : False := by
conv at h => zeta; rw [Nat.zero_add]
/-
y : Nat
h : y + 1 = y
⊢ False
-/
simp_arith at h
```
* Improve namespace resolution. See issue [#1224](https://github.com/leanprover/lean4/issues/1224). Example:
```lean
import Lean
open Lean Parser Elab
open Tactic -- now opens both `Lean.Parser.Tactic` and `Lean.Elab.Tactic`
```
* Rename `constant` command to `opaque`. See discussion at [Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/What.20is.20.60opaque.60.3F/near/284926171).
* Extend `induction` and `cases` syntax: multiple left-hand-sides in a single alternative. This extension is very similar to the one implemented for `match` expressions. Examples:
```lean
inductive Foo where
| mk1 (x : Nat) | mk2 (x : Nat) | mk3
def f (v : Foo) :=
match v with
| .mk1 x => x + 1
| .mk2 x => 2*x + 1
| .mk3 => 1
theorem f_gt_zero : f v > 0 := by
cases v with
| mk1 x | mk2 x => simp_arith! -- New feature used here!
| mk3 => decide
```
* [`let/if` indentation in `do` blocks in now supported.](https://github.com/leanprover/lean4/issues/1120)
* Update Lake to v3.1.1. See the [v3.1.0 release note](https://github.com/leanprover/lake/releases/tag/v3.1.0) for detailed changes.
* Add unnamed antiquotation `$_` for use in syntax quotation patterns.
* [Add unused variables linter](https://github.com/leanprover/lean4/pull/1159). Feedback welcome!
* Lean now generates an error if the body of a declaration body contains a universe parameter that does not occur in the declaration type, nor is an explicit parameter.
Examples:
```lean
/-
The following declaration now produces an error because `PUnit` is universe polymorphic,
but the universe parameter does not occur in the function type `Nat → Nat`
-/
def f (n : Nat) : Nat :=
let aux (_ : PUnit) : Nat := n + 1
aux ⟨⟩
/-
The following declaration is accepted because the universe parameter was explicitly provided in the
function signature.
-/
def g.{u} (n : Nat) : Nat :=
let aux (_ : PUnit.{u}) : Nat := n + 1
aux ⟨⟩
```
* Add `subst_vars` tactic.
* [Fix `autoParam` in structure fields lost in multiple inheritance.](https://github.com/leanprover/lean4/issues/1158).
* Add `[eliminator]` attribute. It allows users to specify default recursor/eliminators for the `induction` and `cases` tactics.
It is an alternative for the `using` notation. Example:
```lean
@[eliminator] protected def recDiag {motive : Nat → Nat → Sort u}
(zero_zero : motive 0 0)
(succ_zero : (x : Nat) → motive x 0 → motive (x + 1) 0)
(zero_succ : (y : Nat) → motive 0 y → motive 0 (y + 1))
(succ_succ : (x y : Nat) → motive x y → motive (x + 1) (y + 1))
(x y : Nat) : motive x y :=
let rec go : (x y : Nat) → motive x y
| 0, 0 => zero_zero
| x+1, 0 => succ_zero x (go x 0)
| 0, y+1 => zero_succ y (go 0 y)
| x+1, y+1 => succ_succ x y (go x y)
go x y
termination_by go x y => (x, y)
def f (x y : Nat) :=
match x, y with
| 0, 0 => 1
| x+1, 0 => f x 0
| 0, y+1 => f 0 y
| x+1, y+1 => f x y
termination_by f x y => (x, y)
example (x y : Nat) : f x y > 0 := by
induction x, y <;> simp [f, *]
```
* Add support for `casesOn` applications to structural and well-founded recursion modules.
This feature is useful when writing definitions using tactics. Example:
```lean
inductive Foo where
| a | b | c
| pair: Foo × Foo → Foo
def Foo.deq (a b : Foo) : Decidable (a = b) := by
cases a <;> cases b
any_goals apply isFalse Foo.noConfusion
any_goals apply isTrue rfl
case pair a b =>
let (a₁, a₂) := a
let (b₁, b₂) := b
exact match deq a₁ b₁, deq a₂ b₂ with
| isTrue h₁, isTrue h₂ => isTrue (by rw [h₁,h₂])
| isFalse h₁, _ => isFalse (fun h => by cases h; cases (h₁ rfl))
| _, isFalse h₂ => isFalse (fun h => by cases h; cases (h₂ rfl))
```
* `Option` is again a monad. The auxiliary type `OptionM` has been removed. See [Zulip thread](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Do.20we.20still.20need.20OptionM.3F/near/279761084).
* Improve `split` tactic. It used to fail on `match` expressions of the form `match h : e with ...` where `e` is not a free variable.
The failure used to occur during generalization.
* New encoding for `match`-expressions that use the `h :` notation for discriminants. The information is not lost during delaboration,
and it is the foundation for a better `split` tactic. at delaboration time. Example:
```lean
#print Nat.decEq
/-
protected def Nat.decEq : (n m : Nat) → Decidable (n = m) :=
fun n m =>
match h : Nat.beq n m with
| true => isTrue (_ : n = m)
| false => isFalse (_ : ¬n = m)
-/
```
* `exists` tactic is now takes a comma separated list of terms.
* Add `dsimp` and `dsimp!` tactics. They guarantee the result term is definitionally equal, and only apply
`rfl`-theorems.
* Fix binder information for `match` patterns that use definitions tagged with `[matchPattern]` (e.g., `Nat.add`).
We now have proper binder information for the variable `y` in the following example.
```lean
def f (x : Nat) : Nat :=
match x with
| 0 => 1
| y + 1 => y
```
* (Fix) the default value for structure fields may now depend on the structure parameters. Example:
```lean
structure Something (i: Nat) where
n1: Nat := 1
n2: Nat := 1 + i
def s : Something 10 := {}
example : s.n2 = 11 := rfl
```
* Apply `rfl` theorems at the `dsimp` auxiliary method used by `simp`. `dsimp` can be used anywhere in an expression
because it preserves definitional equality.
* Refine auto bound implicit feature. It does not consider anymore unbound variables that have the same
name of a declaration being defined. Example:
```lean
def f : f → Bool := -- Error at second `f`
fun _ => true
inductive Foo : List Foo → Type -- Error at second `Foo`
| x : Foo []
```
Before this refinement, the declarations above would be accepted and the
second `f` and `Foo` would be treated as auto implicit variables. That is,
`f : {f : Sort u} → f → Bool`, and
`Foo : {Foo : Type u} → List Foo → Type`.
* Fix syntax hightlighting for recursive declarations. Example
```lean
inductive List (α : Type u) where
| nil : List α -- `List` is not highlighted as a variable anymore
| cons (head : α) (tail : List α) : List α
def List.map (f : α → β) : List α → List β
| [] => []
| a::as => f a :: map f as -- `map` is not highlighted as a variable anymore
```
* Add `autoUnfold` option to `Lean.Meta.Simp.Config`, and the following macros
- `simp!` for `simp (config := { autoUnfold := true })`
- `simp_arith!` for `simp (config := { autoUnfold := true, arith := true })`
- `simp_all!` for `simp_all (config := { autoUnfold := true })`
- `simp_all_arith!` for `simp_all (config := { autoUnfold := true, arith := true })`
When the `autoUnfold` is set to true, `simp` tries to unfold the following kinds of definition
- Recursive definitions defined by structural recursion.
- Non-recursive definitions where the body is a `match`-expression. This
kind of definition is only unfolded if the `match` can be reduced.
Example:
```lean
def append (as bs : List α) : List α :=
match as with
| [] => bs
| a :: as => a :: append as bs
theorem append_nil (as : List α) : append as [] = as := by
induction as <;> simp_all!
theorem append_assoc (as bs cs : List α) : append (append as bs) cs = append as (append bs cs) := by
induction as <;> simp_all!
```
* Add `save` tactic for creating checkpoints more conveniently. Example:
```lean
example : <some-proposition> := by
tac_1
tac_2
save
tac_3
...
```
is equivalent to
```lean
example : <some-proposition> := by
checkpoint
tac_1
tac_2
tac_3
...
```
* Remove support for `{}` annotation from inductive datatype contructors. This annotation was barely used, and we can control the binder information for parameter bindings using the new inductive family indices to parameter promotion. Example: the following declaration using `{}`
```lean
inductive LE' (n : Nat) : Nat → Prop where
| refl {} : LE' n n -- Want `n` to be explicit
| succ : LE' n m → LE' n (m+1)
```
can now be written as
```lean
inductive LE' : Nat → Nat → Prop where
| refl (n : Nat) : LE' n n
| succ : LE' n m → LE' n (m+1)
```
In both cases, the inductive family has one parameter and one index.
Recall that the actual number of parameters can be retrieved using the command `#print`.
* Remove support for `{}` annotation in the `structure` command.
* Several improvements to LSP server. Examples: "jump to definition" in mutually recursive sections, fixed incorrect hover information in "match"-expression patterns, "jump to definition" for pattern variables, fixed auto-completion in function headers, etc.
* In `macro ... xs:p* ...` and similar macro bindings of combinators, `xs` now has the correct type `Array Syntax`
* Identifiers in syntax patterns now ignore macro scopes during matching.
* Improve binder names for constructor auto implicit parameters. Example, given the inductive datatype
```lean
inductive Member : α → List α → Type u
| head : Member a (a::as)
| tail : Member a bs → Member a (b::bs)
```
before:
```lean
#check @Member.head
-- @Member.head : {x : Type u_1} → {a : x} → {as : List x} → Member a (a :: as)
```
now:
```lean
#check @Member.head
-- @Member.head : {α : Type u_1} → {a : α} → {as : List α} → Member a (a :: as)
```
* Improve error message when constructor parameter universe level is too big.
* Add support for `for h : i in [start:stop] do .. ` where `h : i ∈ [start:stop]`. This feature is useful for proving
termination of functions such as:
```lean
inductive Expr where
| app (f : String) (args : Array Expr)
def Expr.size (e : Expr) : Nat := Id.run do
match e with
| app f args =>
let mut sz := 1
for h : i in [: args.size] do
-- h.upper : i < args.size
sz := sz + size (args.get ⟨i, h.upper⟩)
return sz
```
* Add tactic `case'`. It is similar to `case`, but does not admit the goal on failure.
For example, the new tactic is useful when writing tactic scripts where we need to use `case'`
at `first | ... | ...`, and we want to take the next alternative when `case'` fails.
* Add tactic macro
```lean
macro "stop" s:tacticSeq : tactic => `(repeat sorry)
```
See discussion on [Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Partial.20evaluation.20of.20a.20file).
* When displaying goals, we do not display inaccessible proposition names
if they do not have forward dependencies. We still display their types.
For example, the goal
```lean
case node.inl.node
β : Type u_1
b : BinTree β
k : Nat
v : β
left : Tree β
key : Nat
value : β
right : Tree β
ihl : BST left → Tree.find? (Tree.insert left k v) k = some v
ihr : BST right → Tree.find? (Tree.insert right k v) k = some v
h✝ : k < key
a✝³ : BST left
a✝² : ForallTree (fun k v => k < key) left
a✝¹ : BST right
a✝ : ForallTree (fun k v => key < k) right
⊢ BST left
```
is now displayed as
```lean
case node.inl.node
β : Type u_1
b : BinTree β
k : Nat
v : β
left : Tree β
key : Nat
value : β
right : Tree β
ihl : BST left → Tree.find? (Tree.insert left k v) k = some v
ihr : BST right → Tree.find? (Tree.insert right k v) k = some v
: k < key
: BST left
: ForallTree (fun k v => k < key) left
: BST right
: ForallTree (fun k v => key < k) right
⊢ BST left
```
* The hypothesis name is now optional in the `by_cases` tactic.
* [Fix inconsistency between `syntax` and kind names](https://github.com/leanprover/lean4/issues/1090).
The node kinds `numLit`, `charLit`, `nameLit`, `strLit`, and `scientificLit` are now called
`num`, `char`, `name`, `str`, and `scientific` respectively. Example: we now write
```lean
macro_rules | `($n:num) => `("hello")
```
instead of
```lean
macro_rules | `($n:numLit) => `("hello")
```
* (Experimental) New `checkpoint <tactic-seq>` tactic for big interactive proofs.
* Rename tactic `nativeDecide` => `native_decide`.
* Antiquotations are now accepted in any syntax. The `incQuotDepth` `syntax` parser is therefore obsolete and has been removed.
* Renamed tactic `nativeDecide` => `native_decide`.
* "Cleanup" local context before elaborating a `match` alternative right-hand-side. Examples:
```lean
example (x : Nat) : Nat :=
match g x with
| (a, b) => _ -- Local context does not contain the auxiliary `_discr := g x` anymore
example (x : Nat × Nat) (h : x.1 > 0) : f x > 0 := by
match x with
| (a, b) => _ -- Local context does not contain the `h✝ : x.fst > 0` anymore
```
* Improve `let`-pattern (and `have`-pattern) macro expansion. In the following example,
```lean
example (x : Nat × Nat) : f x > 0 := by
let (a, b) := x
done
```
The resulting goal is now `... |- f (a, b) > 0` instead of `... |- f x > 0`.
* Add cross-compiled [aarch64 Linux](https://github.com/leanprover/lean4/pull/1066) and [aarch64 macOS](https://github.com/leanprover/lean4/pull/1076) releases.
* [Add tutorial-like examples to our documentation](https://github.com/leanprover/lean4/tree/master/doc/examples), rendered using LeanInk+Alectryon.
v4.0.0-m4 (23 March 2022)
---------
* `simp` now takes user-defined simp-attributes. You can define a new `simp` attribute by creating a file (e.g., `MySimp.lean`) containing
```lean
import Lean
open Lean.Meta
initialize my_ext : SimpExtension ← registerSimpAttr `my_simp "my own simp attribute"
```
If you don't neet to acces `my_ext`, you can also use the macro
```lean
import Lean
register_simp_attr my_simp "my own simp attribute"
```
Recall that the new `simp` attribute is not active in the Lean file where it was defined.
Here is a small example using the new feature.
```lean
import MySimp
def f (x : Nat) := x + 2
def g (x : Nat) := x + 1
@[my_simp] theorem f_eq : f x = x + 2 := rfl
@[my_simp] theorem g_eq : g x = x + 1 := rfl
example : f x + g x = 2*x + 3 := by
simp_arith [my_simp]
```
* Extend `match` syntax: multiple left-hand-sides in a single alternative. Example:
```lean
def fib : Nat → Nat
| 0 | 1 => 1
| n+2 => fib n + fib (n+1)
```
This feature was discussed at [issue 371](https://github.com/leanprover/lean4/issues/371). It was implemented as a macro expansion. Thus, the following is accepted.
```lean
inductive StrOrNum where
| S (s : String)
| I (i : Int)
def StrOrNum.asString (x : StrOrNum) :=
match x with
| I a | S a => toString a
```
* Improve `#eval` command. Now, when it fails to synthesize a `Lean.MetaEval` instance for the result type, it reduces the type and tries again. The following example now works without additional annotations
```lean
def Foo := List Nat
def test (x : Nat) : Foo :=
[x, x+1, x+2]
#eval test 4
```
* `rw` tactic can now apply auto-generated equation theorems for a given definition. Example:
```lean
example (a : Nat) (h : n = 1) : [a].length = n := by
rw [List.length]
trace_state -- .. |- [].length + 1 = n
rw [List.length]
trace_state -- .. |- 0 + 1 = n
rw [h]
```
* [Fuzzy matching for auto completion](https://github.com/leanprover/lean4/pull/1023)
* Extend dot-notation `x.field` for arrow types. If type of `x` is an arrow, we look up for `Function.field`.
For example, given `f : Nat → Nat` and `g : Nat → Nat`, `f.comp g` is now notation for `Function.comp f g`.
* The new `.<identifier>` notation is now also accepted where a function type is expected.
```lean
example (xs : List Nat) : List Nat := .map .succ xs
example (xs : List α) : Std.RBTree α ord := xs.foldl .insert ∅
```
* [Add code folding support to the language server](https://github.com/leanprover/lean4/pull/1014).
* Support notation `let <pattern> := <expr> | <else-case>` in `do` blocks.
* Remove support for "auto" `pure`. In the [Zulip thread](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/for.2C.20unexpected.20need.20for.20type.20ascription/near/269083574), the consensus seemed to be that "auto" `pure` is more confusing than it's worth.
* Remove restriction in `congr` theorems that all function arguments on the left-hand-side must be free variables. For example, the following theorem is now a valid `congr` theorem.
```lean
@[congr]
theorem dep_congr [DecidableEq ι] {p : ι → Set α} [∀ i, Inhabited (p i)] :
∀ {i j} (h : i = j) (x : p i) (y : α) (hx : x = y), Pi.single (f := (p ·)) i x = Pi.single (f := (p ·)) j ⟨y, hx ▸ h ▸ x.2⟩ :=
```
* [Partially applied congruence theorems.](https://github.com/leanprover/lean4/issues/988)
* Improve elaboration postponement heuristic when expected type is a metavariable. Lean now reduces the expected type before performing the test.
* [Remove deprecated leanpkg](https://github.com/leanprover/lean4/pull/985) in favor of [Lake](https://github.com/leanprover/lake) now bundled with Lean.
* Various improvements to go-to-definition & find-all-references accuracy.
* Auto generated congruence lemmas with support for casts on proofs and `Decidable` instances (see [whishlist](https://github.com/leanprover/lean4/issues/988)).
* Rename option `autoBoundImplicitLocal` => `autoImplicit`.
* [Relax auto-implicit restrictions](https://github.com/leanprover/lean4/pull/1011). The command `set_option relaxedAutoImplicit false` disables the relaxations.
* `contradiction` tactic now closes the goal if there is a `False.elim` application in the target.
* Renamed tatic `byCases` => `by_cases` (motivation: enforcing naming convention).
* Local instances occurring in patterns are now considered by the type class resolution procedure. Example:
```lean
def concat : List ((α : Type) × ToString α × α) → String
| [] => ""
| ⟨_, _, a⟩ :: as => toString a ++ concat as
```
* Notation for providing the motive for `match` expressions has changed.
before:
```lean
match x, rfl : (y : Nat) → x = y → Nat with
| 0, h => ...
| x+1, h => ...
```
now:
```lean
match (motive := (y : Nat) → x = y → Nat) x, rfl with
| 0, h => ...
| x+1, h => ...
```
With this change, the notation for giving names to equality proofs in `match`-expressions is not whitespace sensitive anymore. That is,
we can now write
```lean
match h : sort.swap a b with
| (r₁, r₂) => ... -- `h : sort.swap a b = (r₁, r₂)`
```
* `(generalizing := true)` is the default behavior for `match` expressions even if the expected type is not a proposition. In the following example, we used to have to include `(generalizing := true)` manually.
```lean
inductive Fam : Type → Type 1 where
| any : Fam α
| nat : Nat → Fam Nat
example (a : α) (x : Fam α) : α :=
match x with
| Fam.any => a
| Fam.nat n => n
```
* We now use `PSum` (instead of `Sum`) when compiling mutually recursive definitions using well-founded recursion.
* Better support for parametric well-founded relations. See [issue #1017](https://github.com/leanprover/lean4/issues/1017). This change affects the low-level `termination_by'` hint because the fixed prefix of the function parameters in not "packed" anymore when constructing the well-founded relation type. For example, in the following definition, `as` is part of the fixed prefix, and is not packed anymore. In previous versions, the `termination_by'` term would be written as `measure fun ⟨as, i, _⟩ => as.size - i`
```lean
def sum (as : Array Nat) (i : Nat) (s : Nat) : Nat :=
if h : i < as.size then
sum as (i+1) (s + as.get ⟨i, h⟩)
else
s
termination_by' measure fun ⟨i, _⟩ => as.size - i
```
* Add `while <cond> do <do-block>`, `repeat <do-block>`, and `repeat <do-block> until <cond>` macros for `do`-block. These macros are based on `partial` definitions, and consequently are useful only for writing programs we don't want to prove anything about.
* Add `arith` option to `Simp.Config`, the macro `simp_arith` expands to `simp (config := { arith := true })`. Only `Nat` and linear arithmetic is currently supported. Example:
```lean
example : 0 < 1 + x ∧ x + y + 2 ≥ y + 1 := by
simp_arith
```
* Add `fail <string>?` tactic that always fail.
* Add support for acyclicity at dependent elimination. See [issue #1022](https://github.com/leanprover/lean4/issues/1022).
* Add `trace <string>` tactic for debugging purposes.
* Add nontrivial `SizeOf` instance for types `Unit → α`, and add support for them in the auto-generated `SizeOf` instances for user-defined inductive types. For example, given the inductive datatype
```lean
inductive LazyList (α : Type u) where
| nil : LazyList α
| cons (hd : α) (tl : LazyList α) : LazyList α
| delayed (t : Thunk (LazyList α)) : LazyList α
```
we now have `sizeOf (LazyList.delayed t) = 1 + sizeOf t` instead of `sizeOf (LazyList.delayed t) = 2`.
* Add support for guessing (very) simple well-founded relations when proving termination. For example, the following function does not require a `termination_by` annotation anymore.
```lean
def Array.insertAtAux (i : Nat) (as : Array α) (j : Nat) : Array α :=
if h : i < j then
let as := as.swap! (j-1) j;
insertAtAux i as (j-1)
else
as
```
* Add support for `for h : x in xs do ...` notation where `h : x ∈ xs`. This is mainly useful for showing termination.
* Auto implicit behavior changed for inductive families. An auto implicit argument occurring in inductive family index is also treated as an index (IF it is not fixed, see next item). For example
```lean
inductive HasType : Index n → Vector Ty n → Ty → Type where
```
is now interpreted as
```lean
inductive HasType : {n : Nat} → Index n → Vector Ty n → Ty → Type where
```
* To make the previous feature more convenient to use, we promote a fixed prefix of inductive family indices to parameters. For example, the following declaration is now accepted by Lean
```lean
inductive Lst : Type u → Type u
| nil : Lst α
| cons : α → Lst α → Lst α
```
and `α` in `Lst α` is a parameter. The actual number of parameters can be inspected using the command `#print Lst`. This feature also makes sure we still accept the declaration
```lean
inductive Sublist : List α → List α → Prop
| slnil : Sublist [] []
| cons l₁ l₂ a : Sublist l₁ l₂ → Sublist l₁ (a :: l₂)
| cons2 l₁ l₂ a : Sublist l₁ l₂ → Sublist (a :: l₁) (a :: l₂)
```
* Added auto implicit "chaining". Unassigned metavariables occurring in the auto implicit types now become new auto implicit locals. Consider the following example:
```lean
inductive HasType : Fin n → Vector Ty n → Ty → Type where
| stop : HasType 0 (ty :: ctx) ty
| pop : HasType k ctx ty → HasType k.succ (u :: ctx) ty
```
`ctx` is an auto implicit local in the two constructors, and it has type `ctx : Vector Ty ?m`. Without auto implicit "chaining", the metavariable `?m` will remain unassigned. The new feature creates yet another implicit local `n : Nat` and assigns `n` to `?m`. So, the declaration above is shorthand for
```lean
inductive HasType : {n : Nat} → Fin n → Vector Ty n → Ty → Type where
| stop : {ty : Ty} → {n : Nat} → {ctx : Vector Ty n} → HasType 0 (ty :: ctx) ty
| pop : {n : Nat} → {k : Fin n} → {ctx : Vector Ty n} → {ty : Ty} → HasType k ctx ty → HasType k.succ (u :: ctx) ty
```
* Eliminate auxiliary type annotations (e.g, `autoParam` and `optParam`) from recursor minor premises and projection declarations. Consider the following example
```lean
structure A :=
x : Nat
h : x = 1 := by trivial
example (a : A) : a.x = 1 := by
have aux := a.h
-- `aux` has now type `a.x = 1` instead of `autoParam (a.x = 1) auto✝`
exact aux
example (a : A) : a.x = 1 := by
cases a with
| mk x h =>
-- `h` has now type `x = 1` instead of `autoParam (x = 1) auto✝`
assumption
```
* We now accept overloaded notation in patterns, but we require the set of pattern variables in each alternative to be the same. Example:
```lean
inductive Vector (α : Type u) : Nat → Type u
| nil : Vector α 0
| cons : α → Vector α n → Vector α (n+1)
infix:67 " :: " => Vector.cons -- Overloading the `::` notation
def head1 (x : List α) (h : x ≠ []) : α :=
match x with
| a :: as => a -- `::` is `List.cons` here
def head2 (x : Vector α (n+1)) : α :=
match x with
| a :: as => a -- `::` is `Vector.cons` here
```
* New notation `.<identifier>` based on Swift. The namespace is inferred from the expected type. See [issue #944](https://github.com/leanprover/lean4/issues/944). Examples:
```lean
def f (x : Nat) : Except String Nat :=
if x > 0 then
.ok x
else
.error "x is zero"
namespace Lean.Elab
open Lsp
def identOf : Info → Option (RefIdent × Bool)
| .ofTermInfo ti => match ti.expr with
| .const n .. => some (.const n, ti.isBinder)
| .fvar id .. => some (.fvar id, ti.isBinder)
| _ => none
| .ofFieldInfo fi => some (.const fi.projName, false)
| _ => none
def isImplicit (bi : BinderInfo) : Bool :=
bi matches .implicit
end Lean.Elab
```

View File

@@ -2,32 +2,44 @@
- [What is Lean](./whatIsLean.md)
- [Tour of Lean](./tour.md)
- [Setting Up Lean](./setup.md)
- [Quickstart](./quickstart.md)
- [Setting Up Lean](./quickstart.md)
- [Extended Setup Notes](./setup.md)
- [Theorem Proving in Lean](./tpil.md)
- [Functional Programming in Lean](fplean.md)
- [Examples](./examples.md)
- [Palindromes](examples/palindromes.lean.md)
- [Binary Search Trees](examples/bintree.lean.md)
- [A Certified Type Checker](examples/tc.lean.md)
- [The Well-Typed Interpreter](examples/interp.lean.md)
- [Dependent de Bruijn Indices](examples/deBruijn.lean.md)
- [Parametric Higher-Order Abstract Syntax](examples/phoas.lean.md)
# Language Manual
- [Using Lean](./using_lean.md)
- [Lexical Structure](./lexical_structure.md)
- [Expressions](./expressions.md)
- [Declarations](./declarations.md)
<!-- - [Using Lean](./using_lean.md) -->
<!-- - [Lexical Structure](./lexical_structure.md) -->
<!-- - [Expressions](./expressions.md) -->
<!-- - [Declarations](./declarations.md) -->
- [Organizational features](./organization.md)
- [Sections](./sections.md)
- [Namespaces](./namespaces.md)
- [Implicit Arguments](./implicit.md)
- [Auto Bound Implicit Arguments](./autobound.md)
- [Dependent Types](./deptypes.md)
- [Simple Type Theory](./simptypes.md)
- [Types as objects](./typeobjs.md)
- [Function Abstraction and Evaluation](./funabst.md)
- [Introducing Definitions](./introdef.md)
- [What makes dependent type theory dependent?](./dep.md)
- [Tactics](./tactics.md)
<!-- - [Dependent Types](./deptypes.md) -->
<!-- - [Simple Type Theory](./simptypes.md) -->
<!-- - [Types as objects](./typeobjs.md) -->
<!-- - [Function Abstraction and Evaluation](./funabst.md) -->
<!-- - [Introducing Definitions](./introdef.md) -->
<!-- - [What makes dependent type theory dependent?](./dep.md) -->
<!-- - [Tactics](./tactics.md) -->
- [Syntax Extensions](./syntax.md)
- [The `do` Notation](./do.md)
- [User-defined notation](./notation.md)
- [String Interpolation](./stringinterp.md)
- [User-Defined Notation](./notation.md)
- [Macro Overview](./macro_overview.md)
- [A Guided Example](./syntax_example.md)
- [Elaborators](./elaborators.md)
- [Examples](./syntax_examples.md)
- [Balanced Parentheses](./syntax_example.md)
- [Arithmetic DSL](./metaprogramming-arith.md)
- [Declaring New Types](./decltypes.md)
- [Enumerated Types](./enum.md)
- [Inductive Types](./inductive.md)
@@ -47,7 +59,6 @@
- [Thunk](./thunk.md)
- [Task and Thread](./task.md)
- [Functions](./functions.md)
- [Tactics](./tactics.md)
# Other
@@ -58,16 +69,15 @@
# Development
- [Development Guide](./dev/index.md)
- [Commit Convention](./dev/commit_convention.md)
- [Building Lean](./make/index.md)
- [Ubuntu Setup](./make/ubuntu.md)
- [macOS Setup](./make/osx-10.9.md)
- [Windows MSYS2 Setup](./make/msys2.md)
- [Windows with WSL](./make/wsl.md)
- [Nix Setup (*Experimental*)](./make/nix.md)
- [Foreign Function Interface](./dev/ffi.md)
- [Unit Testing](./dev/testing.md)
- [Building This Manual](./dev/mdbook.md)
- [Fixing Tests](./dev/fixing_tests.md)
- [Bootstrapping](./dev/bootstrap.md)
- [Testing](./dev/testing.md)
- [Debugging](./dev/debugging.md)
- [C++ Coding Style](./dev/cpp_coding_style.md)
- [Commit Convention](./dev/commit_convention.md)
- [Building This Manual](./dev/mdbook.md)
- [Foreign Function Interface](./dev/ffi.md)

786
doc/alectryon.css Normal file
View File

@@ -0,0 +1,786 @@
@charset "UTF-8";
/*
Copyright © 2019 Clément Pit-Claudel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*******************************/
/* CSS reset for .alectryon-io */
/*******************************/
.content {
/*
Use `initial` instead of `contents` to avoid a browser bug which removes
the element from the accessibility tree.
https://developer.mozilla.org/en-US/docs/Web/CSS/display#display_contents
*/
display: initial;
}
.alectryon-io blockquote {
line-height: inherit;
}
.alectryon-io blockquote:after {
display: none;
}
.alectryon-io label {
display: inline;
font-size: inherit;
margin: 0;
}
.alectryon-io a {
text-decoration: none !important;
font-style: oblique !important;
color: unset;
}
/* Undo <small> and <blockquote>, added to improve RSS rendering. */
.alectryon-io small.alectryon-output,
.alectryon-io small.alectryon-type-info {
font-size: inherit;
}
.alectryon-io blockquote.alectryon-goal,
.alectryon-io blockquote.alectryon-message {
font-weight: normal;
font-size: inherit;
}
/***************/
/* Main styles */
/***************/
.alectryon-coqdoc .doc .code,
.alectryon-coqdoc .doc .comment,
.alectryon-coqdoc .doc .inlinecode,
.alectryon-mref,
.alectryon-block, .alectryon-io,
.alectryon-toggle-label, .alectryon-banner {
font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important;
font-size: 0.875em;
font-feature-settings: "COQX" 1 /* Coq ligatures */, "XV00" 1 /* Legacy */, "calt" 1 /* Fallback */;
line-height: initial;
}
.alectryon-io, .alectryon-block, .alectryon-toggle-label, .alectryon-banner {
overflow: visible;
overflow-wrap: break-word;
position: relative;
white-space: pre-wrap;
}
/*
CoqIDE doesn't turn off the unicode bidirectional algorithm (and PG simply
respects the user's `bidi-display-reordering` setting), so don't turn it off
here either. But beware unexpected results like `Definition test_אב := 0.`
.alectryon-io span {
direction: ltr;
unicode-bidi: bidi-override;
}
In any case, make an exception for comments:
.highlight .c {
direction: embed;
unicode-bidi: initial;
}
*/
.alectryon-mref,
.alectryon-mref-marker {
align-self: center;
box-sizing: border-box;
display: inline-block;
font-size: 80%;
font-weight: bold;
line-height: 1;
box-shadow: 0 0 0 1pt black;
padding: 1pt 0.3em;
text-decoration: none;
}
.alectryon-block .alectryon-mref-marker,
.alectryon-io .alectryon-mref-marker {
user-select: none;
margin: -0.25em 0 -0.25em 0.5em;
}
.alectryon-inline .alectryon-mref-marker {
margin: -0.25em 0.15em -0.25em 0.625em; /* 625 = 0.5em / 80% */
}
.alectryon-mref {
color: inherit;
margin: -0.5em 0.25em;
}
.alectryon-goal:target .goal-separator .alectryon-mref-marker,
:target > .alectryon-mref-marker {
animation: blink 0.2s step-start 0s 3 normal none;
background-color: #fcaf3e;
position: relative;
}
@keyframes blink {
50% {
box-shadow: 0 0 0 3pt #fcaf3e, 0 0 0 4pt black;
z-index: 10;
}
}
.alectryon-toggle,
.alectryon-io .alectryon-extra-goal-toggle {
display: none;
}
.alectryon-bubble,
.alectryon-io label,
.alectryon-toggle-label {
cursor: pointer;
}
.alectryon-toggle-label {
display: block;
font-size: 0.8em;
}
.alectryon-io .alectryon-input {
padding: 0.1em 0; /* Enlarge the hitbox slightly to fill interline gaps */
}
.alectryon-io .alectryon-token {
white-space: pre-wrap;
display: inline;
}
.alectryon-io .alectryon-sentence.alectryon-target .alectryon-input {
/* FIXME if keywords were bolder we wouldn't need !important */
font-weight: bold !important; /* Use !important to avoid a * selector */
}
.alectryon-bubble:before,
.alectryon-toggle-label:before,
.alectryon-io label.alectryon-input:after,
.alectryon-io .alectryon-goal > label:before {
border: 1px solid #babdb6;
border-radius: 1em;
box-sizing: border-box;
content: '';
display: inline-block;
font-weight: bold;
height: 0.25em;
margin-bottom: 0.15em;
vertical-align: middle;
width: 0.75em;
}
.alectryon-toggle-label:before,
.alectryon-io .alectryon-goal > label:before {
margin-right: 0.25em;
}
.alectryon-io .alectryon-goal > label:before {
margin-top: 0.125em;
}
.alectryon-io label.alectryon-input {
padding-right: 1em; /* Prevent line wraps before the checkbox bubble */
}
.alectryon-io label.alectryon-input:after {
margin-left: 0.25em;
margin-right: -1em; /* Compensate for the anti-wrapping space */
}
.alectryon-failed {
/* Underlines are broken in Chrome (they reset at each element boundary)… */
/* text-decoration: red wavy underline; */
/* … but it isn't too noticeable with dots */
text-decoration: red dotted underline;
text-decoration-skip-ink: none;
/* Chrome prints background images in low resolution, yielding a blurry underline */
/* background: bottom / 0.3em auto repeat-x url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyLjY0NiAxLjg1MiIgaGVpZ2h0PSI4IiB3aWR0aD0iMTAiPjxwYXRoIGQ9Ik0wIC4yNjVjLjc5NCAwIC41MyAxLjMyMiAxLjMyMyAxLjMyMi43OTQgMCAuNTMtMS4zMjIgMS4zMjMtMS4zMjIiIGZpbGw9Im5vbmUiIHN0cm9rZT0icmVkIiBzdHJva2Utd2lkdGg9Ii41MjkiLz48L3N2Zz4=); */
}
/* Wrapping :hover rules in a media query ensures that tapping a Coq sentence
doesn't trigger its :hover state (otherwise, on mobile, tapping a sentence to
hide its output causes it to remain visible (its :hover state gets triggered.
We only do it for the default style though, since other styles don't put the
output over the main text, so showing too much is not an issue. */
@media (any-hover: hover) {
.alectryon-bubble:hover:before,
.alectryon-toggle-label:hover:before,
.alectryon-io label.alectryon-input:hover:after {
background: #eeeeec;
}
.alectryon-io label.alectryon-input:hover {
text-decoration: underline dotted #babdb6;
text-shadow: 0 0 1px rgb(46, 52, 54, 0.3); /* #2e3436 + opacity */
}
.alectryon-io .alectryon-sentence:hover .alectryon-output,
.alectryon-io .alectryon-token:hover .alectryon-type-info-wrapper,
.alectryon-io .alectryon-token:hover .alectryon-type-info-wrapper {
z-index: 2; /* Place hovered goals above .alectryon-sentence.alectryon-target ones */
}
}
.alectryon-toggle:checked + .alectryon-toggle-label:before,
.alectryon-io .alectryon-sentence > .alectryon-toggle:checked + label.alectryon-input:after,
.alectryon-io .alectryon-extra-goal-toggle:checked + .alectryon-goal > label:before {
background-color: #babdb6;
border-color: #babdb6;
}
/* Disable clicks on sentences when the document-wide toggle is set. */
.alectryon-toggle:checked + label + .alectryon-container label.alectryon-input {
cursor: unset;
pointer-events: none;
}
/* Hide individual checkboxes when the document-wide toggle is set. */
.alectryon-toggle:checked + label + .alectryon-container label.alectryon-input:after {
display: none;
}
/* .alectryon-output is displayed by toggles, :hover, and .alectryon-target rules */
.alectryon-io .alectryon-output {
box-sizing: border-box;
display: none;
left: 0;
right: 0;
position: absolute;
padding: 0.25em 0;
overflow: visible; /* Let box-shadows overflow */
z-index: 1; /* Default to an index lower than that used by :hover */
}
.alectryon-io .alectryon-type-info-wrapper {
position: absolute;
display: inline-block;
width: 100%;
}
.alectryon-io .alectryon-type-info-wrapper.full-width {
left: 0;
min-width: 100%;
max-width: 100%;
}
.alectryon-io .alectryon-type-info .goal-separator {
height: unset;
margin-top: 0em;
}
.alectryon-io .alectryon-type-info-wrapper .alectryon-type-info {
box-sizing: border-box;
bottom: 100%;
position: absolute;
/*padding: 0.25em 0;*/
visibility: hidden;
overflow: visible; /* Let box-shadows overflow */
z-index: 1; /* Default to an index lower than that used by :hover */
white-space: pre-wrap !important;
}
.alectryon-io .alectryon-type-info-wrapper .alectryon-type-info .alectryon-goal.alectryon-docstring {
white-space: pre-wrap !important;
}
@media (any-hover: hover) { /* See note above about this @media query */
.alectryon-io .alectryon-sentence:hover .alectryon-output:not(:hover) {
display: block;
}
.alectryon-io.output-hidden .alectryon-sentence:hover .alectryon-output:not(:hover) {
display: none !important;
}
.alectryon-io.type-info-hidden .alectryon-token:hover .alectryon-type-info-wrapper .alectryon-type-info,
.alectryon-io.type-info-hidden .alectryon-token:hover .alectryon-type-info-wrapper .alectryon-type-info {
/*visibility: hidden !important;*/
}
.alectryon-io .alectryon-token:hover .alectryon-type-info-wrapper .alectryon-type-info,
.alectryon-io .alectryon-token:hover .alectryon-type-info-wrapper .alectryon-type-info {
visibility: visible;
transition-delay: 0.5s;
}
}
.alectryon-io .alectryon-sentence.alectryon-target .alectryon-output {
display: block;
}
/* Indicate active (hovered or targeted) goals with a shadow. */
.alectryon-io .alectryon-sentence:hover .alectryon-output:not(:hover) .alectryon-messages,
.alectryon-io .alectryon-sentence.alectryon-target .alectryon-output .alectryon-messages,
.alectryon-io .alectryon-sentence:hover .alectryon-output:not(:hover) .alectryon-goals,
.alectryon-io .alectryon-sentence.alectryon-target .alectryon-output .alectryon-goals,
.alectryon-io .alectryon-token:hover .alectryon-type-info-wrapper .alectryon-type-info {
box-shadow: 2px 2px 2px gray;
}
.alectryon-io .alectryon-extra-goals .alectryon-goal .goal-hyps {
display: none;
}
.alectryon-io .alectryon-extra-goals .alectryon-extra-goal-toggle:not(:checked) + .alectryon-goal label.goal-separator hr {
/* Dashes indicate that the hypotheses are hidden */
border-top-style: dashed;
}
/* Show just a small preview of the other goals; this is undone by the
"extra-goal" toggle and by :hover and .alectryon-target in windowed mode. */
.alectryon-io .alectryon-extra-goals .alectryon-goal .goal-conclusion {
max-height: 5.2em;
overflow-y: auto;
/* Combining overflow-y: auto with display: inline-block causes extra space
to be added below the box. vertical-align: middle gets rid of it. */
vertical-align: middle;
}
.alectryon-io .alectryon-goals,
.alectryon-io .alectryon-messages {
background: #f6f7f6;
/*border: thin solid #d3d7cf; /* Convenient when pre's background is already #EEE */
display: block;
padding: 0.25em;
}
.alectryon-message::before {
content: '';
float: right;
/* etc/svg/square-bubble-xl.svg */
background: url("data:image/svg+xml,%3Csvg width='14' height='14' viewBox='0 0 3.704 3.704' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill-rule='evenodd' stroke='%23000' stroke-width='.264'%3E%3Cpath d='M.794.934h2.115M.794 1.463h1.455M.794 1.992h1.852'/%3E%3C/g%3E%3Cpath d='M.132.14v2.646h.794v.661l.926-.661h1.72V.14z' fill='none' stroke='%23000' stroke-width='.265'/%3E%3C/svg%3E") top right no-repeat;
height: 14px;
width: 14px;
}
.alectryon-toggle:checked + label + .alectryon-container {
width: unset;
}
/* Show goals when a toggle is set */
.alectryon-toggle:checked + label + .alectryon-container label.alectryon-input + .alectryon-output,
.alectryon-io .alectryon-sentence > .alectryon-toggle:checked ~ .alectryon-output {
display: block;
position: static;
width: unset;
background: unset; /* Override the backgrounds set in floating in windowed mode */
padding: 0.25em 0; /* Re-assert so that later :hover rules don't override this padding */
}
.alectryon-toggle:checked + label + .alectryon-container label.alectryon-input + .alectryon-output .goal-hyps,
.alectryon-io .alectryon-sentence > .alectryon-toggle:checked ~ .alectryon-output .goal-hyps {
/* Overridden back in windowed style */
flex-flow: row wrap;
justify-content: flex-start;
}
.alectryon-toggle:checked + label + .alectryon-container .alectryon-sentence .alectryon-output > div,
.alectryon-io .alectryon-sentence > .alectryon-toggle:checked ~ .alectryon-output > div {
display: block;
}
.alectryon-io .alectryon-extra-goal-toggle:checked + .alectryon-goal .goal-hyps {
display: flex;
}
.alectryon-io .alectryon-extra-goal-toggle:checked + .alectryon-goal .goal-conclusion {
max-height: unset;
overflow-y: unset;
}
.alectryon-toggle:checked + label + .alectryon-container .alectryon-sentence > .alectryon-toggle ~ .alectryon-wsp,
.alectryon-io .alectryon-sentence > .alectryon-toggle:checked ~ .alectryon-wsp {
display: none;
}
.alectryon-io .alectryon-messages,
.alectryon-io .alectryon-message,
.alectryon-io .alectryon-goals,
.alectryon-io .alectryon-goal,
.alectryon-io .goal-hyps > span,
.alectryon-io .goal-conclusion {
border-radius: 0.15em;
}
.alectryon-io .alectryon-goal,
.alectryon-io .alectryon-message {
align-items: center;
background: #f6f7f6;
border: 0em;
display: block;
flex-direction: column;
margin: 0.25em;
padding: 0.5em;
position: relative;
}
.alectryon-io .goal-hyps {
align-content: space-around;
align-items: baseline;
display: flex;
flex-flow: column nowrap; /* re-stated in windowed mode */
justify-content: space-around;
/* LATER use a gap property instead of margins once supported */
margin: -0.15em -0.25em; /* -0.15em to cancel the item spacing */
padding-bottom: 0.35em; /* 0.5em-0.15em to cancel the 0.5em of .goal-separator */
}
.alectryon-io .goal-hyps > br {
display: none; /* Only for RSS readers */
}
.alectryon-io .goal-hyps > span,
.alectryon-io .goal-conclusion {
/*background: #eeeeec;*/
display: inline-block;
padding: 0.15em 0.35em;
}
.alectryon-io .goal-hyps > span {
align-items: baseline;
display: inline-flex;
margin: 0.15em 0.25em;
}
.alectryon-block var,
.alectryon-inline var,
.alectryon-io .goal-hyps > span > var {
font-weight: 600;
font-style: unset;
}
.alectryon-io .goal-hyps > span > var {
/* Shrink the list of names, but let it grow as long as space is available. */
flex-basis: min-content;
flex-grow: 1;
}
.alectryon-io .goal-hyps > span b {
font-weight: 600;
margin: 0 0 0 0.5em;
white-space: pre;
}
.alectryon-io .hyp-body,
.alectryon-io .hyp-type {
display: flex;
align-items: baseline;
}
.alectryon-io .goal-separator {
align-items: center;
display: flex;
flex-direction: row;
height: 1em; /* Fixed height to ignore goal name and markers */
margin-top: -0.5em; /* Compensated in .goal-hyps when shown */
}
.alectryon-io .goal-separator hr {
border: none;
border-top: thin solid #555753;
display: block;
flex-grow: 1;
margin: 0;
}
.alectryon-io .goal-separator .goal-name {
font-size: 0.75em;
margin-left: 0.5em;
}
/**********/
/* Banner */
/**********/
.alectryon-banner {
background: #eeeeec;
border: 1px solid #babcbd;
font-size: 0.75em;
padding: 0.25em;
text-align: center;
margin: 1em 0;
}
.alectryon-banner a {
cursor: pointer;
text-decoration: underline;
}
.alectryon-banner kbd {
background: #d3d7cf;
border-radius: 0.15em;
border: 1px solid #babdb6;
box-sizing: border-box;
display: inline-block;
font-family: inherit;
font-size: 0.9em;
height: 1.3em;
line-height: 1.2em;
margin: -0.25em 0;
padding: 0 0.25em;
vertical-align: middle;
}
/**********/
/* Toggle */
/**********/
.alectryon-toggle-label {
margin: 1rem 0;
}
/******************/
/* Floating style */
/******************/
/* If there's space, display goals to the right of the code, not below it. */
@media (min-width: 80rem) {
/* Unlike the windowed case, we don't want to move output blocks to the side
when they are both :checked and -targeted, since it gets confusing as
things jump around; hence the commented-output part of the selector,
which would otherwise increase specificity */
.alectryon-floating .alectryon-sentence.alectryon-target /* > .alectryon-toggle ~ */ .alectryon-output,
.alectryon-floating .alectryon-sentence:hover .alectryon-output {
top: 0;
left: 100%;
right: -100%;
padding: 0 0.5em;
position: absolute;
}
.alectryon-floating .alectryon-output {
min-height: 100%;
}
.alectryon-floating .alectryon-sentence:hover .alectryon-output {
background: white; /* Ensure that short goals hide long ones */
}
/* This odd margin-bottom property prevents the sticky div from bumping
against the bottom of its container (.alectryon-output). The alternative
would be enlarging .alectryon-output, but that would cause overflows,
enlarging scrollbars and yielding scrolling towards the bottom of the
page. Doing things this way instead makes it possible to restrict
.alectryon-output to a reasonable size (100%, through top = bottom = 0).
See also https://stackoverflow.com/questions/43909940/. */
/* See note on specificity above */
.alectryon-floating .alectryon-sentence.alectryon-target /* > .alectryon-toggle ~ */ .alectryon-output > div,
.alectryon-floating .alectryon-sentence:hover .alectryon-output > div {
margin-bottom: -200%;
position: sticky;
top: 0;
}
.alectryon-floating .alectryon-toggle:checked + label + .alectryon-container .alectryon-sentence .alectryon-output > div,
.alectryon-floating .alectryon-io .alectryon-sentence > .alectryon-toggle:checked ~ .alectryon-output > div {
margin-bottom: unset; /* Undo the margin */
}
/* Float underneath the current fragment
@media (max-width: 80rem) {
.alectryon-floating .alectryon-output {
top: 100%;
}
} */
}
/********************/
/* Multi-pane style */
/********************/
.alectryon-windowed {
border: 0 solid #2e3436;
box-sizing: border-box;
}
.alectryon-windowed .alectryon-sentence:hover .alectryon-output {
background: white; /* Ensure that short goals hide long ones */
}
.alectryon-windowed .alectryon-output {
position: fixed; /* Overwritten by the :checked rules */
}
/* See note about specificity below */
.alectryon-windowed .alectryon-sentence:hover .alectryon-output,
.alectryon-windowed .alectryon-sentence.alectryon-target > .alectryon-toggle ~ .alectryon-output {
padding: 0.5em;
overflow-y: auto; /* Windowed contents may need to scroll */
}
.alectryon-windowed .alectryon-io .alectryon-sentence:hover .alectryon-output:not(:hover) .alectryon-messages,
.alectryon-windowed .alectryon-io .alectryon-sentence.alectryon-target .alectryon-output .alectryon-messages,
.alectryon-windowed .alectryon-io .alectryon-sentence:hover .alectryon-output:not(:hover) .alectryon-goals,
.alectryon-windowed .alectryon-io .alectryon-sentence.alectryon-target .alectryon-output .alectryon-goals {
box-shadow: none; /* A shadow is unnecessary here and incompatible with overflow-y set to auto */
}
.alectryon-windowed .alectryon-io .alectryon-sentence.alectryon-target .alectryon-output .goal-hyps {
/* Restated to override the :checked style */
flex-flow: column nowrap;
justify-content: space-around;
}
.alectryon-windowed .alectryon-sentence.alectryon-target .alectryon-extra-goals .alectryon-goal .goal-conclusion
/* Like .alectryon-io .alectryon-extra-goal-toggle:checked + .alectryon-goal .goal-conclusion */ {
max-height: unset;
overflow-y: unset;
}
.alectryon-windowed .alectryon-output > div {
display: flex; /* Put messages after goals */
flex-direction: column-reverse;
}
/*********************/
/* Standalone styles */
/*********************/
.alectryon-standalone {
font-family: 'IBM Plex Serif', 'PT Serif', 'Merriweather', 'DejaVu Serif', serif;
line-height: 1.5;
}
@media screen and (min-width: 50rem) {
html.alectryon-standalone {
/* Prevent flickering when hovering a block causes scrollbars to appear. */
margin-left: calc(100vw - 100%);
margin-right: 0;
}
}
/* Coqdoc */
.alectryon-coqdoc .doc .code,
.alectryon-coqdoc .doc .inlinecode,
.alectryon-coqdoc .doc .comment {
display: inline;
}
.alectryon-coqdoc .doc .comment {
color: #eeeeec;
}
.alectryon-coqdoc .doc .paragraph {
height: 0.75em;
}
/* Centered, Floating */
.alectryon-standalone .alectryon-centered,
.alectryon-standalone .alectryon-floating {
max-width: 50rem;
margin: auto;
}
@media (min-width: 80rem) {
.alectryon-standalone .alectryon-floating {
max-width: 80rem;
}
.alectryon-standalone .alectryon-floating > * {
width: 50%;
margin-left: 0;
}
}
/* Windowed */
.alectryon-standalone .alectryon-windowed {
display: block;
margin: 0;
overflow-y: auto;
position: absolute;
padding: 0 1em;
}
.alectryon-standalone .alectryon-windowed > * {
/* Override properties of docutils_basic.css */
margin-left: 0;
max-width: unset;
}
.alectryon-standalone .alectryon-windowed .alectryon-io {
box-sizing: border-box;
width: 100%;
}
/* No need to predicate the :hover rules below on :not(:checked), since left,
right, top, and bottom will be inactived by the :checked rules setting
position to static */
/* Specificity: We want the output to stay inline when hovered while unfolded
(:checked), but we want it to move when it's targeted (i.e. when the user
is browsing goals one by one using the keyboard, in which case we want to
goals to appear in consistent locations). The selectors below ensure
that :hover < :checked < -targeted in terms of specificity. */
/* LATER: Reimplement this stuff with CSS variables */
.alectryon-windowed .alectryon-sentence.alectryon-target > .alectryon-toggle ~ .alectryon-output {
position: fixed;
}
@media screen and (min-width: 60rem) {
.alectryon-standalone .alectryon-windowed {
border-right-width: thin;
bottom: 0;
left: 0;
right: 50%;
top: 0;
}
.alectryon-standalone .alectryon-windowed .alectryon-sentence:hover .alectryon-output,
.alectryon-standalone .alectryon-windowed .alectryon-sentence.alectryon-target .alectryon-output {
bottom: 0;
left: 50%;
right: 0;
top: 0;
}
}
@media screen and (max-width: 60rem) {
.alectryon-standalone .alectryon-windowed {
border-bottom-width: 1px;
bottom: 40%;
left: 0;
right: 0;
top: 0;
}
.alectryon-standalone .alectryon-windowed .alectryon-sentence:hover .alectryon-output,
.alectryon-standalone .alectryon-windowed .alectryon-sentence.alectryon-target .alectryon-output {
bottom: 0;
left: 0;
right: 0;
top: 60%;
}
}

190
doc/alectryon.js Normal file
View File

@@ -0,0 +1,190 @@
var Alectryon;
(function(Alectryon) {
(function (slideshow) {
function anchor(sentence) { return "#" + sentence.id; }
function current_sentence() { return slideshow.sentences[slideshow.pos]; }
function unhighlight() {
var sentence = current_sentence();
if (sentence) sentence.classList.remove("alectryon-target");
slideshow.pos = -1;
}
function highlight(sentence) {
sentence.classList.add("alectryon-target");
}
function scroll(sentence) {
// Put the top of the current fragment close to the top of the
// screen, but scroll it out of view if showing it requires pushing
// the sentence past half of the screen. If sentence is already in
// a reasonable position, don't move.
var parent = sentence.parentElement;
/* We want to scroll the whole document, so start at root… */
while (parent && !parent.classList.contains("alectryon-root"))
parent = parent.parentElement;
/* … and work up from there to find a scrollable element.
parent.scrollHeight can be greater than parent.clientHeight
without showing scrollbars, so we add a 10px buffer. */
while (parent && parent.scrollHeight <= parent.clientHeight + 10)
parent = parent.parentElement;
/* <body> and <html> elements can have their client rect overflow
* the window if their height is unset, so scroll the window
* instead */
if (parent && (parent.nodeName == "BODY" || parent.nodeName == "HTML"))
parent = null;
var rect = function(e) { return e.getBoundingClientRect(); };
var parent_box = parent ? rect(parent) : { y: 0, height: window.innerHeight },
sentence_y = rect(sentence).y - parent_box.y,
fragment_y = rect(sentence.parentElement).y - parent_box.y;
// The assertion below sometimes fails for the first element in a block.
// console.assert(sentence_y >= fragment_y);
if (sentence_y < 0.1 * parent_box.height ||
sentence_y > 0.7 * parent_box.height) {
(parent || window).scrollBy(
0, Math.max(sentence_y - 0.5 * parent_box.height,
fragment_y - 0.1 * parent_box.height));
}
}
function highlighted(pos) {
return slideshow.pos == pos;
}
function navigate(pos, inhibitScroll) {
unhighlight();
slideshow.pos = Math.min(Math.max(pos, 0), slideshow.sentences.length - 1);
var sentence = current_sentence();
highlight(sentence);
if (!inhibitScroll)
scroll(sentence);
}
var keys = {
PAGE_UP: 33,
PAGE_DOWN: 34,
ARROW_UP: 38,
ARROW_DOWN: 40,
h: 72, l: 76, p: 80, n: 78
};
function onkeydown(e) {
e = e || window.event;
if (e.ctrlKey || e.metaKey) {
if (e.keyCode == keys.ARROW_UP)
slideshow.previous();
else if (e.keyCode == keys.ARROW_DOWN)
slideshow.next();
else
return;
} else {
// if (e.keyCode == keys.PAGE_UP || e.keyCode == keys.p || e.keyCode == keys.h)
// slideshow.previous();
// else if (e.keyCode == keys.PAGE_DOWN || e.keyCode == keys.n || e.keyCode == keys.l)
// slideshow.next();
// else
return;
}
e.preventDefault();
}
function start() {
slideshow.navigate(0);
}
function toggleHighlight(idx) {
if (highlighted(idx))
unhighlight();
else
navigate(idx, true);
}
function handleClick(evt) {
if (evt.ctrlKey || evt.metaKey) {
var sentence = evt.currentTarget;
// Ensure that the goal is shown on the side, not inline
var checkbox = sentence.getElementsByClassName("alectryon-toggle")[0];
if (checkbox)
checkbox.checked = false;
toggleHighlight(sentence.alectryon_index);
evt.preventDefault();
}
}
function init() {
document.onkeydown = onkeydown;
slideshow.pos = -1;
slideshow.sentences = Array.from(document.getElementsByClassName("alectryon-sentence"));
slideshow.sentences.forEach(function (s, idx) {
s.addEventListener('click', handleClick, false);
s.alectryon_index = idx;
});
}
slideshow.start = start;
slideshow.end = unhighlight;
slideshow.navigate = navigate;
slideshow.next = function() { navigate(slideshow.pos + 1); };
slideshow.previous = function() { navigate(slideshow.pos + -1); };
window.addEventListener('DOMContentLoaded', init);
})(Alectryon.slideshow || (Alectryon.slideshow = {}));
(function (styles) {
var styleNames = ["centered", "floating", "windowed"];
function className(style) {
return "alectryon-" + style;
}
function setStyle(style) {
var root = document.getElementsByClassName("alectryon-root")[0];
styleNames.forEach(function (s) {
root.classList.remove(className(s)); });
root.classList.add(className(style));
}
function init() {
var banner = document.getElementsByClassName("alectryon-banner")[0];
if (banner) {
banner.append(" Style: ");
styleNames.forEach(function (styleName, idx) {
var s = styleName;
var a = document.createElement("a");
a.onclick = function() { setStyle(s); };
a.append(styleName);
if (idx > 0) banner.append("; ");
banner.appendChild(a);
});
banner.append(".");
}
}
window.addEventListener('DOMContentLoaded', init);
styles.setStyle = setStyle;
})(Alectryon.styles || (Alectryon.styles = {}));
})(Alectryon || (Alectryon = {}));
function setHidden(elements, isVisible, token) {
for (let i = 0; i < elements.length; i++) {
if (isVisible) {
elements[i].classList.remove(token)
} else {
elements[i].classList.add(token)
}
}
}
function toggleShowTypes(checkbox) {
setHidden(document.getElementsByClassName("alectryon-io"), checkbox.checked, "type-info-hidden")
}
function toggleShowGoals(checkbox) {
setHidden(document.getElementsByClassName("alectryon-io"), checkbox.checked, "output-hidden")
}

View File

@@ -36,9 +36,9 @@ Note that, Lean inferred a more general type using `Sort` instead of `Type`.
Although we love this feature and use it extensively when implementing Lean,
we realize some users may feel uncomfortable with it. Thus, you can disable it using
the command `set_option autoBoundImplicitLocal false`.
the command `set_option autoImplicit false`.
```lean
set_option autoBoundImplicitLocal false
set_option autoImplicit false
/- The following definition produces `unknown identifier` errors -/
-- def compose (g : β → γ) (f : α → β) (x : α) : γ :=
-- g (f x)

View File

@@ -10,6 +10,12 @@ build-dir = "out"
[output.html]
git-repository-url = "https://github.com/leanprover/lean4"
additional-css = ["alectryon.css", "pygments.css"]
additional-js = ["alectryon.js"]
[output.html.fold]
enable = true
level = 0
[output.html.playground.boring-prefixes]
lean = "# "

View File

@@ -675,6 +675,20 @@ When a ``match`` has only one line, the vertical bar may be left out. In that ca
def bar₄ (p : Nat × Nat) : Nat :=
let ⟨m, n⟩ := p in m + n
Information about the term being matched can be preserved in each branch using the syntax `match h : t with`. For example, a user may want to match a term `ns ++ ms : List Nat`, while tracking the hypothesis `ns ++ ms = []` or `ns ++ ms= h :: t` in the respective match arm:
```lean
def foo (ns ms : List Nat) (h1 : ns ++ ms ≠ []) (k : Nat -> Char) : Char :=
match h2 : ns ++ ms with
-- in this arm, we have the hypothesis `h2 : ns ++ ms = []`
| [] => absurd h2 h1
-- in this arm, we have the hypothesis `h2 : ns ++ ms = h :: t`
| h :: t => k h
-- '7'
#eval foo [7, 8, 9] [] (by decide) Nat.digitChar
```
.. _structures_and_records:
Structures and Records

View File

@@ -1,4 +1,3 @@
# Lean Build Bootstrapping
Since version 4, Lean is a partially bootstrapped program: most parts of the
@@ -16,17 +15,18 @@ stage0/
bin/lean
stage1/
include/
config.h # config variables used to build `lean` such as use allocator
runtime/lean.h # runtime headers, used by extracted C code, uses `config.h`
config.h # config variables used to build `lean` such as used allocator
runtime/lean.h # runtime header, used by extracted C code, uses `config.h`
share/lean/
Makefile # used by `leanmake`
lean.mk # used by `leanmake`
lib/
lean/**/*.olean # the Lean library (incl. the compiler) compiled by the previous stage's `lean`
temp/**/*.{c,o} # the library extracted to C and compiled by `leanc`
libInit.a libStd.a libLean.a # static libraries of the Lean library
libleancpp.a # a static library of the C++ sources of Lean
libleanshared.so # a dynamic library including the static libraries above
bin/
lean # the Lean compiler & server linked together from the above libraries
lean # the Lean compiler & server, a small executable that calls directly into libleanshared.so
leanc # a wrapper around a C compiler supplying search paths etc
leanmake # a wrapper around `make` supplying the Makefile above
stage2/...
@@ -55,7 +55,7 @@ We are not aware of any "meta-meta" parts that influence more than two stages of
compilation, so stage 3 should always be identical to stage 2 and only exists as
a sanity check.
In summary, doing a standard build via `make` involves these steps:
In summary, doing a standard build via `make` internally involves these steps:
1. compile the `stage0/src` archived sources into `stage0/bin/lean`
1. use it to compile the current library (*including* your changes) into `stage1/lib`
@@ -119,4 +119,4 @@ affect later stages. This is an issue in two specific cases.
To modify either of these flags both for building and editing the stdlib, adjust
the code in `stage0/src/stdlib_flags.h`. The flags will automatically be reset
on the next `update-stage0` when the file is overwritten with the original
version in `src/`.
version in `src/`.

View File

@@ -1,155 +0,0 @@
[google-style]: https://google.github.io/styleguide/cppguide.html
[cpplint]: /src/cmake/Modules/cpplint.py
# Coding Style
The Lean project is moving away from using any C++ as more and more of
the compiler is being bootstrapped in Lean itself. But the remaining
C++ codebase is using modified version of [Google's C++ Style
Guide][google-style].
## [C++11](http://en.wikipedia.org/wiki/C%2B%2B11) features
Lean makes extensive use of new features in the C++ 11 standard.
Developers must be familiar with the standard to be able to understand
the code. Here are some of the features that are extensively used.
- Type inference (aka `auto` keyword).
- Initializer lists.
- Lambda functions and expressions.
- `nullptr` constant.
- Strongly typed enumerations.
- Right angle brackets with no space is now allowed in C++ 11.
- Thread local storage.
- Threading facilities.
- Tuple types.
- Smart pointers.
- When using ``std::list`` make sure to include the `std::`
qualifier so you do not accidentally use the ``lean::list`` type.
- When using ``std::copy`` make sure to include the `std::`
qualifier so you do not accidentally use the ``lean::copy`` type.
- Small and focused functions are preferred: foo(). Try not to
exceed 500 lines in a function, except in tests.
- Do **not** use the `#ifndef-#define-#endif` idiom for header files.
Instead use `#pragma once`.
- Write `type const & v` instead of `const type & v`.
- Use `const` extensively.
- Use the macro `lean_assert` for assertions. The macro `lean_assert`
is extensively used when writing unit tests.
## Naming
- Class, method, and function names are lower case
Use `_` for composite names. Example: `type_checker`.
- Class/struct fields should start with the prefix `m_`.
Example:
```c++
class point {
int m_x;
int m_y;
public:
...
};
```
## Namespaces
All code is in the `lean` namespace. Each frontend is stored in a
separate nested namespace. For example, the SMT 2.0 frontend is stored
in the `lean::smt` namespace.
Exception: some debugging functions are stored outside of the `lean`
namespace. These functions are called `print` and are meant to be used
when debugging Lean using `gdb`.
Do not use `using namespace` in a header file.
## Templates
Organize template source code using the approach described at http://www.codeproject.com/Articles/3515/How-To-Organize-Template-Source-Code
## Idioms
Use some popular C++ idioms:
- [Pimpl](http://c2.com/cgi/wiki?PimplIdiom)
- [RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) Resource Acquisition Is Initialization
## Formatting
* Use 4 spaces for indentation.
* `if-then-else` curly brackets not always required. The following
forms are acceptable:
```c++
if (cond) {
...
} else {
...
}
```
and
```c++
if (cond)
statement1;
else
statement2;
```
In *exceptional cases*, we also use
```c++
if (cond) statement;
```
and
```c++
if (cond) statement1; else stament2;
```
* `if-then-else-if-else`
The following forms are acceptable:
```c++
if (cond) {
...
} else if (cond) {
...
} else {
...
}
```c++
and
```c++
if (cond)
statement1;
else if (cond)
statement2;
else
statement3;
```
* Format code using extra spaces to make code more readable. For example:
```c++
environment const & m_env;
cache m_cache;
normalizer m_normalizer;
volatile bool m_interrupted;
```
instead of:
```c++
environment const & m_env;
cache m_cache;
normalizer m_normalizer;
volatile bool m_interrupted;
```
* Spaces in expressions. Write `a == b` instead of `a==b`. Similarly,
we write `x < y + 1` instead of `x<y+1`.

View File

@@ -20,8 +20,9 @@ Notable trace classes:
* `Meta.isDefEq`: unification
* `interpreter`: full execution trace of the interpreter. Only available in debug builds.
In pure contexts or when execution is aborted before the messages are finally printed, one can instead use the term `dbg_trace "msg with {interpolations}"; val` (`;` can also be replaced by a newline), which will print the message directly to stderr before evaluating `val`. `dbgTraceVal val` can be used as a shorthand for `dbg_trace "{val}"; val`.
In pure contexts or when execution is aborted before the messages are finally printed, one can instead use the term `dbg_trace "msg with {interpolations}"; val` (`;` can also be replaced by a newline), which will print the message to stderr before evaluating `val`. `dbgTraceVal val` can be used as a shorthand for `dbg_trace "{val}"; val`.
Note that if the return value is not actually used, the trace code is silently dropped as well.
In the language server, stderr output is buffered and shown as messages after a command has been elaborated, unless the option `server.stderrAsMessages` is deactivated.
## Debuggers

View File

@@ -66,33 +66,45 @@ Return values and `@[export]` parameters are always owned at the moment.
## Initialization
When including Lean code as part of a larger program, modules must be *initialized* before accessing any of their declarations.
Module initialization entails
* initialization of all "constants" (nullary functions), including closed terms lifted out of other functions
* execution of all `[init]` functions
* execution of all `[builtinInit]` functions, if the `builtin` parameter of the module initializer has been set
The module initializer is automatically run with the `builtin` flag for executables compiled from Lean code and for "plugins" loaded with `lean --plugin`.
For all other modules imported by `lean`, the initializer is run without `builtin`.
Thus `[init]` functions are run iff their module is imported, regardless of whether they have native code available or not, while `[builtinInit]` functions are only run for native executable or plugins, regardless of whether their module is imported or not.
`lean` uses built-in initializers for e.g. registering basic parsers that should be available even without importing their module (which is necessary for bootstrapping).
The initializer for module `A.B` is called `initialize_A_B` and will automatically initialize any imported modules.
Module initializers are idempotent, but not thread-safe.
Module initializers are idempotent (when run with the same `builtin` flag), but not thread-safe.
Together with initialization of the Lean runtime, you should execute code like the following exactly once before accessing any Lean declarations:
```c
void lean_initialize_runtime_module();
void lean_initialize();
lean_object * initialize_A_B(lean_object *);
lean_object * initialize_C(lean_object *);
lean_object * initialize_A_B(uint8_t builtin, lean_object *);
lean_object * initialize_C(uint8_t builtin, lean_object *);
...
lean_initialize_runtime_module();
//lean_initialize(); // necessary if you (indirectly) access the `Lean` package
lean_object * res;
res = initialize_A_B(lean_io_mk_world());
// use same default as for Lean executables
uint8_t builtin = 1;
res = initialize_A_B(builtin, lean_io_mk_world());
if (lean_io_result_is_ok(res)) {
lean_dec_ref(res);
} else {
lean_io_result_show_error(res);
lean_dec(res);
return ...; // do not access Lean declarations if initialization failed
return ...; // do not access Lean declarations if initialization failed
}
res = initialize_C(lean_io_mk_world());
res = initialize_C(builtin, lean_io_mk_world());
if (lean_io_result_is_ok(res)) {
...
//lean_init_task_manager(); // necessary if you (indirectly) use `Task`
//lean_init_task_manager(); // necessary if you (indirectly) use `Task`
lean_io_mark_end_initialization();
```

View File

@@ -1,39 +0,0 @@
Fixing Tests
============
The test suite contains some tests that compare the produced output
with the expected output. For example, the directory `tests/lean`
contains files such as [`bad_class.lean`](../tests/lean/bad_class.lean) and
[`bad_class.lean.expected.out`](../tests/lean/bad_class.lean.expected.out).
The later contains the expected output for the test file `bad_class.lean`.
When the Lean source code or the standard library are modified, some of these
tests break because the produced output is slightly different, and we have
to reflect the changes in the `.lean.expected.out` files.
We should not blindly copy the new produced output since we may accidentally
miss a bug introduced by recent changes.
The test suite contains commands that allow us to see what changed in a convenient way.
First, we must install [meld](http://meldmerge.org/). On Ubuntu, we can do it by simply executing
```
sudo apt-get install meld
```
Now, suppose `bad_class.lean` test is broken. We can see the problem by going to `test/lean` directory and
executing
```
./test_single.sh -i bad_class.lean
```
When the `-i` option is provided, `meld` is automatically invoked
whenever there is discrepancy between the produced and expected
outputs. `meld` can also be used to repair the problems.
In Emacs, we can also execute `M-x lean4-diff-test-file` to check/diff the file of the current buffer.
To mass-copy all `.produced.out` files to the respective `.expected.out` file, use `tests/lean/copy-produced`.
When using the Nix setup, add `--keep-failed` to the `nix build` call and then call
```sh
tests/lean/copy-produced <build-dir>/source/tests/lean
```
instead where `<build-dir>` is the path printed out by `nix build`.

View File

@@ -1,48 +1,30 @@
# Development Workflow
- [Commit Convention](./commit_convention.md)
- [Building Lean](../make/index.md)
- [Ubuntu Setup](../make/ubuntu.md)
- [macOS Setup](../make/osx-10.9.md)
- [Windows MSYS2 Setup](../make/msys2.md)
- [Windows with WSL](../make/wsl.md)
- [Nix Setup (*Experimental*)](../make/nix.md)
- [Unit Testing](./testing.md)
- [Building This Manual](./mdbook.md)
- [Fixing Tests](./fixing_tests.md)
- [Debugging](./debugging.md)
- [C++ Coding Style](./dev/cpp_coding_style.md)
You will notice there is a `stage0` folder. This is for bootstrapping
the compiler development. Generally you do not change any code in
`stage0` manually. It is important that you read [bootstrapping
pipeline](bootstrap.md) so you understand how this works.
If you want to make changes to Lean itself, start by [building Lean](../make/index.html) from a clean checkout to make sure that everything is set up correctly.
After that, read on below to find out how to set up your editor for changing the Lean source code, followed by further sections of the development manual where applicable such as on the [test suite](testing.md) and [commit convention](commit_convention.md).
The dev team uses `elan` to manage which `lean` toolchain to use
locally and `elan` can be used to setup the version of Lean you are
manually building. This means you generally do not use `make
install`. You use `elan` instead.
If you are planning to make any changes that may affect the compilation of Lean itself, e.g. changes to the parser, elaborator, or compiler, you should first read about the [bootstrapping pipeline](bootstrap.md).
You should not edit the `stage0` directory except using the commands described in that section when necessary.
## Development Setup
You can use any of the [supported editors](../setup.md) for editing
the Lean source code. If you set up `elan` as below, opening `src/` as
a *workspace folder* should ensure that stage 0 will be used for file
in that directory.
You can use any of the [supported editors](../setup.md) for editing the Lean source code.
If you set up `elan` as below, opening `src/` as a *workspace folder* should ensure that stage 0 (i.e. the stage that first compiles `src/`) will be used for files in that directory.
## Dev setup using elan
### Dev setup using elan
You can use [`elan`](https://github.com/leanprover/elan) to easily
switch between stages and build configurations based on the current
directory, both for the `lean`, `leanc`, and `leanmake` binaries in your shell's
PATH and inside your editor.
To install elan, you can do so, without installing a default version of Lean, using
To install elan, you can do so, without installing a default version of Lean, using (Unix)
```bash
[Unix]
curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh -s -- --default-toolchain none
[Windows]
```
or (Windows)
```
curl -O --location https://raw.githubusercontent.com/leanprover/elan/master/elan-init.ps1
powershell -f elan-init.ps1 --default-toolchain none
del elan-init.ps1
@@ -63,6 +45,7 @@ cd src
# make `lean` etc. point to stage0 anywhere inside `src`
elan override set lean4-stage0
```
You can also use the `+toolchain` shorthand (e.g. `lean +lean4-debug`) to switch
toolchains on the spot. `lean4-mode` will automatically use the `lean` executable
associated with the directory of the current file as long as `lean4-rootdir` is

View File

@@ -1,8 +1,6 @@
# Unit Testing
# Test Suite
You can run the unit tests after completing a build using the following:
After [building lean](../make/index.md) you can run all the tests using
After [building Lean](../make/index.md) you can run all the tests using
```
cd build/release
make test ARGS=-j4
@@ -29,10 +27,11 @@ ctest -j 4 --output-on-failure --timeout 300
To get verbose output from ctest pass the `--verbose` command line
option. Test output is normally suppressed and only summary
information is displayed. This option will show all test output
information is displayed. This option will show all test output.
Here is the summary of the test source code organization.
All these tests are included by [/src/shell/CMakeLists.txt](https://github.com/leanprover/lean4/blob/master/src/shell/CMakeLists.txt):
## Test Suite Organization
All these tests are included by [src/shell/CMakeLists.txt](https://github.com/leanprover/lean4/blob/master/src/shell/CMakeLists.txt):
- `tests/lean`: contains tests that come equipped with a
.lean.expected.out file. The driver script `test_single.sh` runs
@@ -88,11 +87,35 @@ All these tests are included by [/src/shell/CMakeLists.txt](https://github.com/l
- `tests/plugin`: tests that compiled Lean code can be loaded into
`lean` via the `--plugin` command line option.
- `tests/leanpkg`: tests the `leanpkg` program, where each sub-folder
is a complete "lean package", including:
- `cyclic`
- `user_ext`
- `user_attr`
- `user_opt`
- `prv`
- `user_attr_app`
## Fixing Tests
When the Lean source code or the standard library are modified, some of the
tests break because the produced output is slightly different, and we have
to reflect the changes in the `.lean.expected.out` files.
We should not blindly copy the new produced output since we may accidentally
miss a bug introduced by recent changes.
The test suite contains commands that allow us to see what changed in a convenient way.
First, we must install [meld](http://meldmerge.org/). On Ubuntu, we can do it by simply executing
```
sudo apt-get install meld
```
Now, suppose `bad_class.lean` test is broken. We can see the problem by going to `test/lean` directory and
executing
```
./test_single.sh -i bad_class.lean
```
When the `-i` option is provided, `meld` is automatically invoked
whenever there is discrepancy between the produced and expected
outputs. `meld` can also be used to repair the problems.
In Emacs, we can also execute `M-x lean4-diff-test-file` to check/diff the file of the current buffer.
To mass-copy all `.produced.out` files to the respective `.expected.out` file, use `tests/lean/copy-produced`.
When using the Nix setup, add `--keep-failed` to the `nix build` call and then call
```sh
tests/lean/copy-produced <build-dir>/source/tests/lean
```
instead where `<build-dir>` is the path printed out by `nix build`.

View File

@@ -276,8 +276,8 @@ def sum (xs : Array Nat) : IO Nat := do
-- x: 3
-- 6
-- We can write pure code using the `do` DSL too.
def sum' (xs : Array Nat) : Nat := do
-- We can write pure code using the `Id.run <| do` DSL too.
def sum' (xs : Array Nat) : Nat := Id.run <| do
let mut s := 0
for x in xs do
s := s + x
@@ -348,6 +348,46 @@ TODO: describe `forIn`
TODO
## Returning early from a failed match
Inside a `do` block, the pattern `let _ ← <success> | <fail>` will continue with the rest of the block if the match on the left hand side succeeds, but will execute the right hand side and exit the block on failure:
```lean
def showUserInfo (getUsername getFavoriteColor : IO (Option String)) : IO Unit := do
let some n getUsername | IO.println "no username!"
IO.println s!"username: {n}"
let some c getFavoriteColor | IO.println "user didn't provide a favorite color!"
IO.println s!"favorite color: {c}"
-- username: JohnDoe
-- favorite color: red
#eval showUserInfo (pure <| some "JohnDoe") (pure <| some "red")
-- no username
#eval showUserInfo (pure none) (pure <| some "purple")
-- username: JaneDoe
-- user didn't provide a favorite color
#eval showUserInfo (pure <| some "JaneDoe") (pure none)
```
## If-let
Inside a `do` block, users can employ the `if let` pattern to destructure actions:
```lean
def tryIncrement (getInput : IO (Option Nat)) : IO (Except String Nat) := do
if let some n getInput
then return Except.ok n.succ
else return Except.error "argument was `none`"
-- Except.ok 2
#eval tryIncrement (pure <| some 1)
-- Except.error "argument was `none`"
#eval tryIncrement (pure <| none)
```
## Pattern matching
TODO

8
doc/elaborators.md Normal file
View File

@@ -0,0 +1,8 @@
## Elaborators
TODO. See [Lean Together 2021: Metaprogramming in Lean
4](https://youtu.be/hxQ1vvhYN_U) for an overview as well [the
continuation](https://youtu.be/vy4JWIiiXSY) about tactic programming.
For more information on antiquotations, see also §4.1 of [Beyond
Notations: Hygienic Macro Expansion for Theorem Proving
Languages](https://arxiv.org/pdf/2001.10490.pdf#page=11).

9
doc/examples.md Normal file
View File

@@ -0,0 +1,9 @@
Examples
========
- [Palindromes](examples/palindromes.lean.md)
- [Binary Search Trees](examples/bintree.lean.md)
- [A Certified Type Checker](examples/tc.lean.md)
- [The Well-Typed Interpreter](examples/interp.lean.md)
- [Dependent de Bruijn Indices](examples/deBruijn.lean.md)
- [Parametric Higher-Order Abstract Syntax](examples/phoas.lean.md)

View File

@@ -0,0 +1,22 @@
/- "Hello world" -/
#eval "hello" ++ " " ++ "world"
-- "hello world"
#check true
-- Bool
def x := 10
#eval x + 2
-- 12
def double (x : Int) := 2*x
#eval double 3
-- 6
#check double
-- Int → Int
example : double 4 = 8 := rfl

View File

@@ -0,0 +1,19 @@
/- Dependent pattern matching -/
inductive Vector (α : Type u) : Nat Type u
| nil : Vector α 0
| cons : α Vector α n Vector α (n+1)
infix:67 "::" => Vector.cons
def Vector.zip : Vector α n Vector β n Vector (α × β) n
| nil, nil => nil
| a::as, b::bs => (a, b) :: zip as bs
#print Vector.zip
/-
def Vector.zip.{u_1, u_2} : {α : Type u_1} → {n : Nat} → {β : Type u_2} → Vector α n → Vector β n → Vector (α × β) n :=
fun {α} {n} {β} x x_1 =>
Vector.brecOn (motive := fun {n} x => {β : Type u_2} → Vector β n → Vector (α × β) n) x
...
-/

View File

@@ -0,0 +1,22 @@
/- Structures -/
structure Point where
x : Int := 0
y : Int := 0
deriving Repr
#eval Point.x (Point.mk 10 20)
-- 10
#eval { x := 10, y := 20 : Point }
def p : Point := { y := 20 }
#eval p.x
#eval p.y
#eval { p with x := 5 }
-- { x := 5, y := 20 }
structure Point3D extends Point where
z : Int

View File

@@ -0,0 +1,28 @@
/- Type classes -/
namespace Example
class ToString (α : Type u) where
toString : α String
#check @ToString.toString
-- {α : Type u_1} → [self : ToString α] → α → String
instance : ToString String where
toString s := s
instance : ToString Bool where
toString b := if b then "true" else "false"
#eval ToString.toString "hello"
export ToString (toString)
#eval toString true
-- "true"
-- #eval toString (true, "hello") -- Error
instance [ToString α] [ToString β] : ToString (α × β) where
toString p := "(" ++ toString p.1 ++ ", " ++ toString p.2 ++ ")"
#eval toString (true, "hello")
-- "(true, hello)"
end Example

View File

@@ -0,0 +1,44 @@
/- Type classes are heavily used in Lean -/
namespace Example
class Mul (α : Type u) where
mul : α α α
infixl:70 " * " => Mul.mul
def double [Mul α] (a : α) := a * a
class Semigroup (α : Type u) extends Mul α where
mul_assoc : a b c : α, (a * b) * c = a * (b * c)
instance : Semigroup Nat where
mul := Nat.mul
mul_assoc := Nat.mul_assoc
#eval double 5
class Functor (f : Type u Type v) : Type (max (u+1) v) where
map : (α β) f α f β
infixr:100 " <$> " => Functor.map
class LawfulFunctor (f : Type u Type v) [Functor f] : Prop where
id_map (x : f α) : id <$> x = x
comp_map (g : α β) (h : β γ) (x : f α) :(h g) <$> x = h <$> g <$> x
end Example
/-
`Deriving instances automatically`
We have seen `deriving Repr` in a few examples.
It is an instance generator.
Lean comes equipped with generators for the following classes.
`Repr`, `Inhabited`, `BEq`, `DecidableEq`,
`Hashable`, `Ord`, `FromToJson`, `SizeOf`
-/
inductive Tree (α : Type u) where
| leaf (val : α)
| node (left right : Tree α)
deriving DecidableEq, Ord, Inhabited, Repr

View File

@@ -0,0 +1,31 @@
/- Tactics -/
example : p q p q p := by
intro hp hq
apply And.intro
exact hp
apply And.intro
exact hq
exact hp
example : p q p q p := by
intro hp hq; apply And.intro hp; exact And.intro hq hp
/- Structuring proofs -/
example : p q p q p := by
intro hp hq
apply And.intro
case left => exact hp
case right =>
apply And.intro
case left => exact hq
case right => exact hp
example : p q p q p := by
intro hp hq
apply And.intro
. exact hp
. apply And.intro
. exact hq
. exact hp

View File

@@ -0,0 +1,19 @@
/- intro tactic variants -/
example (p q : α Prop) : ( x, p x q x) x, q x p x := by
intro h
match h with
| Exists.intro w (And.intro hp hq) => exact Exists.intro w (And.intro hq hp)
example (p q : α Prop) : ( x, p x q x) x, q x p x := by
intro (Exists.intro _ (And.intro hp hq))
exact Exists.intro _ (And.intro hq hp)
example (p q : α Prop) : ( x, p x q x) x, q x p x := by
intro _, hp, hq
exact _, hq, hp
example (α : Type) (p q : α Prop) : ( x, p x q x) x, q x p x := by
intro
| _, .inl h => exact _, .inr h
| _, .inr h => exact _, .inl h

View File

@@ -0,0 +1,12 @@
/- Inaccessible names -/
example : x y : Nat, x = y y = x := by
intros
apply Eq.symm
assumption
example : x y : Nat, x = y y = x := by
intros
apply Eq.symm
rename_i a b hab
exact hab

View File

@@ -0,0 +1,19 @@
/- More tactics -/
example (p q : Nat Prop) : ( x, p x q x) x, q x p x := by
intro h
cases h with
| intro x hpq =>
cases hpq with
| intro hp hq =>
exists x
example : p q q p := by
intro p
cases p
constructor <;> assumption
example : p ¬ p q := by
intro h
cases h
contradiction

View File

@@ -0,0 +1,20 @@
/- Structuring proofs (cont.) -/
example : p (q r) (p q) (p r) := by
intro h
have hp : p := h.left
have hqr : q r := h.right
show (p q) (p r)
cases hqr with
| inl hq => exact Or.inl hp, hq
| inr hr => exact Or.inr hp, hr
example : p (q r) (p q) (p r) := by
intro hp, hqr
cases hqr with
| inl hq =>
have := And.intro hp hq
apply Or.inl; exact this
| inr hr =>
have := And.intro hp hr
apply Or.inr; exact this

View File

@@ -0,0 +1,10 @@
/- Tactic combinators -/
example : p q r p ((p q) r) (q r p) := by
intros
repeat (any_goals constructor)
all_goals assumption
example : p q r p ((p q) r) (q r p) := by
intros
repeat (any_goals (first | assumption | constructor))

View File

@@ -0,0 +1,14 @@
/- First-class functions -/
def twice (f : Nat Nat) (a : Nat) :=
f (f a)
#check twice
-- (Nat → Nat) → Nat → Nat
#eval twice (fun x => x + 2) 10
theorem twice_add_2 (a : Nat) : twice (fun x => x + 2) a = a + 4 := rfl
-- `(· + 2)` is syntax sugar for `(fun x => x + 2)`.
#eval twice (· + 2) 10

View File

@@ -0,0 +1,22 @@
/- Rewriting -/
example (f : Nat Nat) (k : Nat) (h₁ : f 0 = 0) (h₂ : k = 0) : f k = 0 := by
rw [h₂] -- replace k with 0
rw [h₁] -- replace f 0 with 0
example (f : Nat Nat) (k : Nat) (h₁ : f 0 = 0) (h₂ : k = 0) : f k = 0 := by
rw [h₂, h₁]
example (f : Nat Nat) (a b : Nat) (h₁ : a = b) (h₂ : f a = 0) : f b = 0 := by
rw [ h₁, h₂]
example (f : Nat Nat) (a : Nat) (h : 0 + a = 0) : f a = f 0 := by
rw [Nat.zero_add] at h
rw [h]
def Tuple (α : Type) (n : Nat) :=
{ as : List α // as.length = n }
example (n : Nat) (h : n = 0) (t : Tuple α n) : Tuple α 0 := by
rw [h] at t
exact t

View File

@@ -0,0 +1,21 @@
/- Simplifier -/
example (p : Nat Prop) : (x + 0) * (0 + y * 1 + z * 0) = x * y := by
simp
example (p : Nat Prop) (h : p (x * y)) : p ((x + 0) * (0 + y * 1 + z * 0)) := by
simp; assumption
example (p : Nat Prop) (h : p ((x + 0) * (0 + y * 1 + z * 0))) : p (x * y) := by
simp at h; assumption
def f (m n : Nat) : Nat :=
m + n + m
example (h : n = 1) (h' : 0 = m) : (f m n) = n := by
simp [h, h', f]
example (p : Nat Prop) (h₁ : x + 0 = x') (h₂ : y + 0 = y')
: x + y + 0 = x' + y' := by
simp at *
simp [*]

View File

@@ -0,0 +1,13 @@
/- Simplifier -/
def mk_symm (xs : List α) :=
xs ++ xs.reverse
@[simp] theorem reverse_mk_symm : (mk_symm xs).reverse = mk_symm xs := by
simp [mk_symm]
theorem tst : (xs ++ mk_symm ys).reverse = mk_symm ys ++ xs.reverse := by
simp
#print tst
-- Lean reverse_mk_symm, and List.reverse_append

View File

@@ -0,0 +1,26 @@
/- split tactic -/
def f (x y z : Nat) : Nat :=
match x, y, z with
| 5, _, _ => y
| _, 5, _ => y
| _, _, 5 => y
| _, _, _ => 1
example : x 5 y 5 z 5 z = w f x y w = 1 := by
intros
simp [f]
split
. contradiction
. contradiction
. contradiction
. rfl
def g (xs ys : List Nat) : Nat :=
match xs, ys with
| [a, b], _ => a+b+1
| _, [b, c] => b+1
| _, _ => 1
example (xs ys : List Nat) (h : g xs ys = 0) : False := by
unfold g at h; split at h <;> simp_arith at h

View File

@@ -0,0 +1,9 @@
/- induction tactic -/
example (as : List α) (a : α) : (as.concat a).length = as.length + 1 := by
induction as with
| nil => rfl
| cons x xs ih => simp [List.concat, ih]
example (as : List α) (a : α) : (as.concat a).length = as.length + 1 := by
induction as <;> simp! [*]

View File

@@ -0,0 +1,59 @@
/- Enumerated types -/
inductive Weekday where
| sunday | monday | tuesday | wednesday
| thursday | friday | saturday
#check Weekday.sunday
-- Weekday
open Weekday
#check sunday
def natOfWeekday (d : Weekday) : Nat :=
match d with
| sunday => 1
| monday => 2
| tuesday => 3
| wednesday => 4
| thursday => 5
| friday => 6
| saturday => 7
def Weekday.next (d : Weekday) : Weekday :=
match d with
| sunday => monday
| monday => tuesday
| tuesday => wednesday
| wednesday => thursday
| thursday => friday
| friday => saturday
| saturday => sunday
def Weekday.previous : Weekday Weekday
| sunday => saturday
| monday => sunday
| tuesday => monday
| wednesday => tuesday
| thursday => wednesday
| friday => thursday
| saturday => friday
/- Proving theorems using tactics -/
theorem Weekday.next_previous (d : Weekday) : d.next.previous = d :=
match d with
| sunday => rfl
| monday => rfl
| tuesday => rfl
| wednesday => rfl
| thursday => rfl
| friday => rfl
| saturday => rfl
theorem Weekday.next_previous' (d : Weekday) : d.next.previous = d := by -- switch to tactic mode
cases d -- Creates 7 goals
rfl; rfl; rfl; rfl; rfl; rfl; rfl
theorem Weekday.next_previous'' (d : Weekday) : d.next.previous = d := by
cases d <;> rfl

View File

@@ -0,0 +1,20 @@
/- What is the type of Nat? -/
#check 0
-- Nat
#check Nat
-- Type
#check Type
-- Type 1
#check Type 1
-- Type 2
#check Eq.refl 2
-- 2 = 2
#check 2 = 2
-- Prop
#check Prop
-- Type
example : Prop = Sort 0 := rfl
example : Type = Sort 1 := rfl
example : Type 1 = Sort 2 := rfl

View File

@@ -0,0 +1,21 @@
/- Implicit arguments and universe polymorphism -/
def f (α β : Sort u) (a : α) (b : β) : α := a
#eval f Nat String 1 "hello"
-- 1
def g {α β : Sort u} (a : α) (b : β) : α := a
#eval g 1 "hello"
def h (a : α) (b : β) : α := a
#check g
-- ?m.1 → ?m.2 → ?m.1
#check @g
-- {α β : Sort u} → α → β → α
#check @h
-- {α : Sort u_1} → {β : Sort u_2} → α → β → α
#check g (α := Nat) (β := String)
-- Nat → String → Nat

View File

@@ -0,0 +1,14 @@
/- Inductive Types -/
inductive Tree (β : Type v) where
| leaf
| node (left : Tree β) (key : Nat) (value : β) (right : Tree β)
deriving Repr
#eval Tree.node .leaf 10 true .leaf
-- Tree.node Tree.leaf 10 true Tree.leaf
inductive Vector (α : Type u) : Nat Type u
| nil : Vector α 0
| cons : α Vector α n Vector α (n+1)

View File

@@ -0,0 +1,25 @@
/- Recursive functions -/
#print Nat -- Nat is an inductive datatype
def fib (n : Nat) : Nat :=
match n with
| 0 => 1
| 1 => 1
| n+2 => fib (n+1) + fib n
example : fib 5 = 8 := rfl
example : fib (n+2) = fib (n+1) + fib n := rfl
#print fib
/-
def fib : Nat → Nat :=
fun n =>
Nat.brecOn n fun n f =>
(match (motive := (n : Nat) → Nat.below n → Nat) n with
| 0 => fun x => 1
| 1 => fun x => 1
| Nat.succ (Nat.succ n) => fun x => x.fst.fst + x.fst.snd.fst.fst)
f
-/

View File

@@ -0,0 +1,25 @@
/- Well-founded recursion -/
def ack : Nat Nat Nat
| 0, y => y+1
| x+1, 0 => ack x 1
| x+1, y+1 => ack x (ack (x+1) y)
termination_by ack x y => (x, y)
def sum (a : Array Int) : Int :=
let rec go (i : Nat) :=
if i < a.size then
a[i] + go (i+1)
else
0
go 0
termination_by go i => a.size - i
set_option pp.proofs true
#print sum.go
/-
def sum.go : Array Int → Nat → Int :=
fun a =>
WellFounded.fix (sum.go.proof_1 a) fun i a_1 =>
if h : i < Array.size a then Array.getOp a i + a_1 (i + 1) (sum.go.proof_2 a i h) else 0
-/

View File

@@ -0,0 +1,44 @@
/- Mutual recursion -/
inductive Term where
| const : String Term
| app : String List Term Term
namespace Term
mutual
def numConsts : Term Nat
| const _ => 1
| app _ cs => numConstsLst cs
def numConstsLst : List Term Nat
| [] => 0
| c :: cs => numConsts c + numConstsLst cs
end
mutual
def replaceConst (a b : String) : Term Term
| const c => if a = c then const b else const c
| app f cs => app f (replaceConstLst a b cs)
def replaceConstLst (a b : String) : List Term List Term
| [] => []
| c :: cs => replaceConst a b c :: replaceConstLst a b cs
end
/- Mutual recursion in theorems -/
mutual
theorem numConsts_replaceConst (a b : String) (e : Term)
: numConsts (replaceConst a b e) = numConsts e := by
match e with
| const c => simp [replaceConst]; split <;> simp [numConsts]
| app f cs => simp [replaceConst, numConsts, numConsts_replaceConstLst a b cs]
theorem numConsts_replaceConstLst (a b : String) (es : List Term)
: numConstsLst (replaceConstLst a b es) = numConstsLst es := by
match es with
| [] => simp [replaceConstLst, numConstsLst]
| c :: cs =>
simp [replaceConstLst, numConstsLst, numConsts_replaceConst a b c,
numConsts_replaceConstLst a b cs]
end

295
doc/examples/bintree.lean Normal file
View File

@@ -0,0 +1,295 @@
/-!
# Binary Search Trees
If the type of keys can be totally ordered -- that is, it supports a well-behaved `≤` comparison --
then maps can be implemented with binary search trees (BSTs). Insert and lookup operations on BSTs take time
proportional to the height of the tree. If the tree is balanced, the operations therefore take logarithmic time.
This example is based on a similar example found in the ["Sofware Foundations"](https://softwarefoundations.cis.upenn.edu/vfa-current/SearchTree.html)
book (volume 3).
-/
/-!
We use `Nat` as the key type in our implementation of BSTs,
since it has a convenient total order with lots of theorems and automation available.
We leave as an exercise to the reader the generalization to arbitrary types.
-/
inductive Tree (β : Type v) where
| leaf
| node (left : Tree β) (key : Nat) (value : β) (right : Tree β)
deriving Repr
/-!
The function `contains` returns `true` iff the given tree contains the key `k`.
-/
def Tree.contains (t : Tree β) (k : Nat) : Bool :=
match t with
| leaf => false
| node left key value right =>
if k < key then
left.contains k
else if key < k then
right.contains k
else
true
/-!
`t.find? k` returns `some v` if `v` is the value bound to key `k` in the tree `t`. It returns `none` otherwise.
-/
def Tree.find? (t : Tree β) (k : Nat) : Option β :=
match t with
| leaf => none
| node left key value right =>
if k < key then
left.find? k
else if key < k then
right.find? k
else
some value
/-!
`t.insert k v` is the map containing all the bindings of `t` along with a binding of `k` to `v`.
-/
def Tree.insert (t : Tree β) (k : Nat) (v : β) : Tree β :=
match t with
| leaf => node leaf k v leaf
| node left key value right =>
if k < key then
node (left.insert k v) key value right
else if key < k then
node left key value (right.insert k v)
else
node left k v right
/-!
Let's add a new operation to our tree: converting it to an association list that contains the key--value bindings from the tree stored as pairs.
If that list is sorted by the keys, then any two trees that represent the same map would be converted to the same list.
Here's a function that does so with an in-order traversal of the tree.
-/
def Tree.toList (t : Tree β) : List (Nat × β) :=
match t with
| leaf => []
| node l k v r => l.toList ++ [(k, v)] ++ r.toList
#eval Tree.leaf.insert 2 "two"
|>.insert 3 "three"
|>.insert 1 "one"
#eval Tree.leaf.insert 2 "two"
|>.insert 3 "three"
|>.insert 1 "one"
|>.toList
/-!
The implemention of `Tree.toList` is inefficient because of how it uses the `++` operator.
On a balanced tree its running time is linearithmic, because it does a linear number of
concatentations at each level of the tree. On an unbalanced tree it's quadratic time.
Here's a tail-recursive implementation than runs in linear time, regardless of whether the tree is balanced:
-/
def Tree.toListTR (t : Tree β) : List (Nat × β) :=
go t []
where
go (t : Tree β) (acc : List (Nat × β)) : List (Nat × β) :=
match t with
| leaf => acc
| node l k v r => l.go ((k, v) :: r.go acc)
/-!
We now prove that `t.toList` and `t.toListTR` return the same list.
The proof is on induction, and as we used the auxiliary function `go`
to define `Tree.toListTR`, we use the auxiliary theorem `go` to prove the theorem.
The proof of the auxiliary theorem is by induction on `t`.
The `generalizing acc` modifier instructs Lean to revert `acc`, apply the
induction theorem for `Tree`s, and then reintroduce `acc` in each case.
By using `generalizing`, we obtain the more general induction hypotheses
- `left_ih : ∀ acc, toListTR.go left acc = toList left ++ acc`
- `right_ih : ∀ acc, toListTR.go right acc = toList right ++ acc`
Recall that the combinator `tac <;> tac'` runs `tac` on the main goal and `tac'` on each produced goal,
concatenating all goals produced by `tac'`. In this theorem, we use it to apply
`simp` and close each subgoal produced by the `induction` tactic.
The `simp` parameters `toListTR.go` and `toList` instruct the simplifier to try to reduce
and/or apply auto generated equation theorems for these two functions.
The parameter `*` intructs the simplifier to use any equation in a goal as rewriting rules.
In this particular case, `simp` uses the induction hypotheses as rewriting rules.
Finally, the parameter `List.append_assoc` intructs the simplifier to use the
`List.append_assoc` theorem as a rewriting rule.
-/
theorem Tree.toList_eq_toListTR (t : Tree β)
: t.toList = t.toListTR := by
simp [toListTR, go t []]
where
go (t : Tree β) (acc : List (Nat × β))
: toListTR.go t acc = t.toList ++ acc := by
induction t generalizing acc <;>
simp [toListTR.go, toList, *, List.append_assoc]
/-!
The `[csimp]` annotation instructs the Lean code generator to replace
any `Tree.toList` with `Tree.toListTR` when generating code.
-/
@[csimp] theorem Tree.toList_eq_toListTR_csimp
: @Tree.toList = @Tree.toListTR := by
funext β t
apply toList_eq_toListTR
/-!
The implementations of `Tree.find?` and `Tree.insert` assume that values of type tree obey the BST invariant:
for any non-empty node with key `k`, all the values of the `left` subtree are less than `k` and all the values
of the right subtree are greater than `k`. But that invariant is not part of the definition of tree.
So, let's formalize the BST invariant. Here's one way to do so. First, we define a helper `ForallTree`
to express that idea that a predicate holds at every node of a tree:
-/
inductive ForallTree (p : Nat β Prop) : Tree β Prop
| leaf : ForallTree p .leaf
| node :
ForallTree p left
p key value
ForallTree p right
ForallTree p (.node left key value right)
/-!
Second, we define the BST invariant:
An empty tree is a BST.
A non-empty tree is a BST if all its left nodes have a lesser key, its right nodes have a greater key, and the left and right subtrees are themselves BSTs.
-/
inductive BST : Tree β Prop
| leaf : BST .leaf
| node :
ForallTree (fun k v => k < key) left
ForallTree (fun k v => key < k) right
BST left BST right
BST (.node left key value right)
/-!
We can use the `macro` command to create helper tactics for organizing our proofs.
The macro `have_eq x y` tries to prove `x = y` using linear arithmetic, and then
immediately uses the new equality to substitute `x` with `y` everywhere in the goal.
The modifier `local` specifies the scope of the macro.
-/
/-- The `have_eq lhs rhs` tactic (tries to) prove that `lhs = rhs`,
and then replaces `lhs` with `rhs`. -/
local macro "have_eq " lhs:term:max rhs:term:max : tactic =>
`((have h : $lhs:term = $rhs:term :=
-- TODO: replace with linarith
by simp_arith at *; apply Nat.le_antisymm <;> assumption
try subst $lhs:term))
/-!
The `by_cases' e` is just the regular `by_cases` followed by `simp` using all
hypotheses in the current goal as rewriting rules.
Recall that the `by_cases` tactic creates two goals. One where we have `h : e` and
another one containing `h : ¬ e`. The simplier uses the `h` to rewrite `e` to `True`
in the first subgoal, and `e` to `False` in the second. This is particularly
useful if `e` is the condition of an `if`-statement.
-/
/-- `by_cases' e` is a shorthand form `by_cases e <;> simp[*]` -/
local macro "by_cases' " e:term : tactic =>
`(by_cases $e:term <;> simp [*])
/-!
We can use the attribute `[simp]` to instruct the simplifier to reduce given definitions or
apply rewrite theorems. The `local` modifier limits the scope of this modification to this file.
-/
attribute [local simp] Tree.insert
/-!
We now prove that `Tree.insert` preserves the BST invariant using induction and case analysis.
Recall that the tactic `. tac` focuses on the main goal and tries to solve it using `tac`, or else fails.
It is used to structure proofs in Lean.
The notation `e` is just syntax sugar for `(by assumption : e)`. That is, it tries to find a hypothesis `h : e`.
It is useful to access hypothesis that have auto generated names (aka "inaccessible") names.
-/
theorem Tree.forall_insert_of_forall
(h₁ : ForallTree p t) (h₂ : p key value)
: ForallTree p (t.insert key value) := by
induction h₁ with
| leaf => exact .node .leaf h₂ .leaf
| node hl hp hr ihl ihr =>
rename Nat => k
by_cases' key < k
. exact .node ihl hp hr
. by_cases' k < key
. exact .node hl hp ihr
. have_eq key k
exact .node hl h₂ hr
theorem Tree.bst_insert_of_bst
{t : Tree β} (h : BST t) (key : Nat) (value : β)
: BST (t.insert key value) := by
induction h with
| leaf => exact .node .leaf .leaf .leaf .leaf
| node h₁ h₂ b₁ b₂ ih₁ ih₂ =>
rename Nat => k
simp
by_cases' key < k
. exact .node (forall_insert_of_forall h₁ key < k) h₂ ih₁ b₂
. by_cases' k < key
. exact .node h₁ (forall_insert_of_forall h₂ k < key) b₁ ih₂
. have_eq key k
exact .node h₁ h₂ b₁ b₂
/-!
Now, we define the type `BinTree` using a `Subtype` that states that only trees satisfying the BST invariant are `BinTree`s.
-/
def BinTree (β : Type u) := { t : Tree β // BST t }
def BinTree.mk : BinTree β :=
.leaf, .leaf
def BinTree.contains (b : BinTree β) (k : Nat) : Bool :=
b.val.contains k
def BinTree.find? (b : BinTree β) (k : Nat) : Option β :=
b.val.find? k
def BinTree.insert (b : BinTree β) (k : Nat) (v : β) : BinTree β :=
b.val.insert k v, b.val.bst_insert_of_bst b.property k v
/-!
Finally, we prove that `BinTree.find?` and `BinTree.insert` satisfy the map properties.
-/
attribute [local simp]
BinTree.mk BinTree.contains BinTree.find?
BinTree.insert Tree.find? Tree.contains Tree.insert
theorem BinTree.find_mk (k : Nat)
: BinTree.mk.find? k = (none : Option β) := by
simp
theorem BinTree.find_insert (b : BinTree β) (k : Nat) (v : β)
: (b.insert k v).find? k = some v := by
let t, h := b; simp
induction t with simp
| node left key value right ihl ihr =>
by_cases' k < key
. cases h; apply ihl; assumption
. by_cases' key < k
cases h; apply ihr; assumption
theorem BinTree.find_insert_of_ne (b : BinTree β) (h : k k') (v : β)
: (b.insert k v).find? k' = b.find? k' := by
let t, h := b; simp
induction t with simp
| leaf =>
split <;> simp <;> split <;> simp
have_eq k k'
contradiction
| node left key value right ihl ihr =>
let .node hl hr bl br := h
specialize ihl bl
specialize ihr br
by_cases' k < key; by_cases' key < k
have_eq key k
by_cases' k' < k; by_cases' k < k'
have_eq k k'
contradiction

View File

@@ -0,0 +1,5 @@
(this example is rendered by Alectryon in the CI)
```lean
{{#include bintree.lean}}
```

163
doc/examples/deBruijn.lean Normal file
View File

@@ -0,0 +1,163 @@
/-!
# Dependent de Bruijn Indices
In this example, we represent program syntax terms in a type family parameterized by a list of types,
representing the typing context, or information on which free variables are in scope and what
their types are.
Remark: this example is based on an example in the book [Certified Programming with Dependent Types](http://adam.chlipala.net/cpdt/) by Adam Chlipala.
-/
/-!
Programmers who move to statically typed functional languages from scripting languages
often complain about the requirement that every element of a list have the same type. With
fancy type systems, we can partially lift this requirement. We can index a list type with a
“type-level” list that explains what type each element of the list should have. This has been
done in a variety of ways in Haskell using type classes, and we can do it much more cleanly
and directly in Lean.
We parameterize our heterogeneous lists by at type `α` and an `α`-indexed type `β`.
-/
inductive HList {α : Type v} (β : α Type u) : List α Type (max u v)
| nil : HList β []
| cons : β i HList β is HList β (i::is)
/-!
We overload the `List.cons` notation `::` so we can also use it to create
heterogeneous lists.
-/
infix:67 " :: " => HList.cons
/-! We similarly overload the `List` notation `[]` for the empty heterogeneous list. -/
notation "[" "]" => HList.nil
/-!
Variables are represented in a way isomorphic to the natural numbers, where
number 0 represents the first element in the context, number 1 the second element, and so
on. Actually, instead of numbers, we use the `Member` inductive family.
The value of type `Member a as` can be viewed as a certificate that `a` is
an element of the list `as`. The constructor `Member.head` says that `a`
is in the list if the list begins with it. The constructor `Member.tail`
says that if `a` is in the list `bs`, it is also in the list `b::bs`.
-/
inductive Member : α List α Type
| head : Member a (a::as)
| tail : Member a bs Member a (b::bs)
/-!
Given a heterogeneous list `HList β is` and value of type `Member i is`, `HList.get`
retrieves an element of type `β i` from the list.
The pattern `.head` and `.tail h` are sugar for `Member.head` and `Member.tail h` respectively.
Lean can infer the namespace using the expected type.
-/
def HList.get : HList β is Member i is β i
| a::as, .head => a
| a::as, .tail h => as.get h
/-!
Here is the definition of the simple type system for our programming language, a simply typed
lambda calculus with natural numbers as the base type.
-/
inductive Ty where
| nat
| fn : Ty Ty Ty
/-!
We can write a function to translate `Ty` values to a Lean type
— remember that types are first class, so can be calculated just like any other value.
We mark `Ty.denote` as `[reducible]` to make sure the typeclass resolution procedure can
unfold/reduce it. For example, suppose Lean is trying to synthesize a value for the instance
`Add (Ty.denote Ty.nat)`. Since `Ty.denote` is marked as `[reducible]`,
the typeclass resolution procedure can reduce `Ty.denote Ty.nat` to `Nat`, and use
the builtin instance for `Add Nat` as the solution.
Recall that the term `a.denote` is sugar for `denote a` where `denote` is the function being defined.
We call it the "dot notation".
-/
@[reducible] def Ty.denote : Ty Type
| nat => Nat
| fn a b => a.denote b.denote
/-!
Here is the definition of the `Term` type, including variables, constants, addition,
function application and abstraction, and let binding of local variables.
Since `let` is a keyword in Lean, we use the "escaped identifier" `«let»`.
You can input the unicode (French double quotes) using `\f<<` (for `«`) and `\f>>` (for `»`).
The term `Term ctx .nat` is sugar for `Term ctx Ty.nat`, Lean infers the namespace using the expected type.
-/
inductive Term : List Ty Ty Type
| var : Member ty ctx Term ctx ty
| const : Nat Term ctx .nat
| plus : Term ctx .nat Term ctx .nat Term ctx .nat
| app : Term ctx (.fn dom ran) Term ctx dom Term ctx ran
| lam : Term (dom :: ctx) ran Term ctx (.fn dom ran)
| «let» : Term ctx ty₁ Term (ty₁ :: ctx) ty₂ Term ctx ty₂
/-!
Here are two example terms encoding, the first addition packaged as a two-argument
curried function, and the second of a sample application of addition to constants.
The command `open Ty Term Member` opens the namespaces `Ty`, `Term`, and `Member`. Thus,
you can write `lam` instead of `Term.lam`.
-/
open Ty Term Member
def add : Term [] (fn nat (fn nat nat)) :=
lam (lam (plus (var (tail head)) (var head)))
def three_the_hard_way : Term [] nat :=
app (app add (const 1)) (const 2)
/-!
Since dependent typing ensures that any term is well-formed in its context and has a particular type,
it is easy to translate syntactic terms into Lean values.
The attribute `[simp]` instructs Lean to always try to unfold `Term.denote` applications when one applies
the `simp` tactic. We also say this is a hint for the Lean term simplifier.
-/
@[simp] def Term.denote : Term ctx ty HList Ty.denote ctx ty.denote
| var h, env => env.get h
| const n, _ => n
| plus a b, env => a.denote env + b.denote env
| app f a, env => f.denote env (a.denote env)
| lam b, env => fun x => b.denote (x :: env)
| «let» a b, env => b.denote (a.denote env :: env)
/-!
You can show that the denotation of `three_the_hard_way` is indeed `3` using reflexivity.
-/
example : three_the_hard_way.denote [] = 3 :=
rfl
/-!
We now define the constant folding optimization that traverses a term if replaces subterms such as
`plus (const m) (const n)` with `const (n+m)`.
-/
@[simp] def Term.constFold : Term ctx ty Term ctx ty
| const n => const n
| var h => var h
| app f a => app f.constFold a.constFold
| lam b => lam b.constFold
| «let» a b => «let» a.constFold b.constFold
| plus a b =>
match a.constFold, b.constFold with
| const n, const m => const (n+m)
| a', b' => plus a' b'
/-!
The correctness of the `Term.constFold` is proved using induction, case-analysis, and the term simplifier.
We prove all cases but the one for `plus` using `simp [*]`. This tactic instructs the term simplifier to
use hypotheses such as `a = b` as rewriting/simplications rules.
We use the `split` to break the nested `match` expression in the `plus` case into two cases.
The local variables `iha` and `ihb` are the induction hypotheses for `a` and `b`.
The modifier `←` in a term simplifier argument instructs the term simplier to use the equation as a rewriting rule in
the "reverse direction. That is, given `h : a = b`, `← h` instructs the term simplifier to rewrite `b` subterms to `a`.
-/
theorem Term.constFold_sound (e : Term ctx ty) : e.constFold.denote env = e.denote env := by
induction e with simp [*]
| plus a b iha ihb =>
split
next he₁ he₂ => simp [ iha, ihb, he₁, he₂]
next => simp [iha, ihb]

View File

@@ -0,0 +1,5 @@
(this example is rendered by Alectryon in the CI)
```lean
{{#include deBruijn.lean}}
```

152
doc/examples/interp.lean Normal file
View File

@@ -0,0 +1,152 @@
/-!
# The Well-Typed Interpreter
In this example, we build an interpreter for a simple functional programming language,
with variables, function application, binary operators and an `if...then...else` construct.
We will use the dependent type system to ensure that any programs which can be represented are well-typed.
Remark: this example is based on an example found in the Idris manual.
-/
/-!
Vectors
--------
A `Vector` is a list of size `n` whose elements belong to a type `α`.
-/
inductive Vector (α : Type u) : Nat Type u
| nil : Vector α 0
| cons : α Vector α n Vector α (n+1)
/-!
We can overload the `List.cons` notation `::` and use it to create `Vector`s.
-/
infix:67 " :: " => Vector.cons
/-!
Now, we define the types of our simple functional language.
We have integers, booleans, and functions, represented by `Ty`.
-/
inductive Ty where
| int
| bool
| fn (a r : Ty)
/-!
We can write a function to translate `Ty` values to a Lean type
— remember that types are first class, so can be calculated just like any other value.
We mark `Ty.interp` as `[reducible]` to make sure the typeclass resolution procedure can
unfold/reduce it. For example, suppose Lean is trying to synthesize a value for the instance
`Add (Ty.interp Ty.int)`. Since `Ty.interp` is marked as `[reducible]`,
the typeclass resolution procedure can reduce `Ty.interp Ty.int` to `Int`, and use
the builtin instance for `Add Int` as the solution.
-/
@[reducible] def Ty.interp : Ty Type
| int => Int
| bool => Bool
| fn a r => a.interp r.interp
/-!
Expressions are indexed by the types of the local variables, and the type of the expression itself.
-/
inductive HasType : Fin n Vector Ty n Ty Type where
| stop : HasType 0 (ty :: ctx) ty
| pop : HasType k ctx ty HasType k.succ (u :: ctx) ty
inductive Expr : Vector Ty n Ty Type where
| var : HasType i ctx ty Expr ctx ty
| val : Int Expr ctx Ty.int
| lam : Expr (a :: ctx) ty Expr ctx (Ty.fn a ty)
| app : Expr ctx (Ty.fn a ty) Expr ctx a Expr ctx ty
| op : (a.interp b.interp c.interp) Expr ctx a Expr ctx b Expr ctx c
| ife : Expr ctx Ty.bool Expr ctx a Expr ctx a Expr ctx a
| delay : (Unit Expr ctx a) Expr ctx a
/-!
We use the command `open` to create the aliases `stop` and `pop` for `HasType.stop` and `HasType.pop` respectively.
-/
open HasType (stop pop)
/-!
Since expressions are indexed by their type, we can read the typing rules of the language from the definitions of the constructors.
Let us look at each constructor in turn.
We use a nameless representation for variables — they are de Bruijn indexed.
Variables are represented by a proof of their membership in the context, `HasType i ctx ty`,
which is a proof that variable `i` in context `ctx` has type `ty`.
We can treat `stop` as a proof that the most recently defined variable is well-typed,
and `pop n` as a proof that, if the `n`th most recently defined variable is well-typed, so is the `n+1`th.
In practice, this means we use `stop` to refer to the most recently defined variable,
`pop stop` to refer to the next, and so on, via the `Expr.var` constructor.
A value `Expr.val` carries a concrete representation of an integer.
A lambda `Expr.lam` creates a function. In the scope of a function ot type `Ty.fn a ty`, there is a
new local variable of type `a`.
A function application `Expr.app` produces a value of type `ty` given a function from `a` to `ty` and a value of type `a`.
The constructor `Expr.op` allows us to use arbitrary binary operators, where the type of the operator informs what the types of the arguments must be.
Finally, the constructor `Exp.ife` represents a `if-then-else` expression. The condition is a Boolean, and each branch must have the same type.
The auxiliary constructor `Expr.delay` is used to delay evaluation.
-/
/-!
When we evaluate an `Expr`, well need to know the values in scope, as well as their types. `Env` is an environment,
indexed over the types in scope. Since an environment is just another form of list, albeit with a strongly specified connection
to the vector of local variable types, we overload again the notation `::` so that we can use the usual list syntax.
Given a proof that a variable is defined in the context, we can then produce a value from the environment.
-/
inductive Env : Vector Ty n Type where
| nil : Env Vector.nil
| cons : Ty.interp a Env ctx Env (a :: ctx)
infix:67 " :: " => Env.cons
def Env.lookup : HasType i ctx ty Env ctx ty.interp
| stop, x :: xs => x
| pop k, x :: xs => lookup k xs
/-!
Given this, an interpreter is a function which translates an `Expr` into a Lean value with respect to a specific environment.
-/
def Expr.interp (env : Env ctx) : Expr ctx ty ty.interp
| var i => env.lookup i
| val x => x
| lam b => fun x => b.interp (Env.cons x env)
| app f a => f.interp env (a.interp env)
| op o x y => o (x.interp env) (y.interp env)
| ife c t e => if c.interp env then t.interp env else e.interp env
| delay a => (a ()).interp env
open Expr
/-!
We can make some simple test functions. Firstly, adding two inputs `fun x y => y + x` is written as follows.
-/
def add : Expr ctx (Ty.fn Ty.int (Ty.fn Ty.int Ty.int)) :=
lam (lam (op (·+·) (var stop) (var (pop stop))))
#eval add.interp Env.nil 10 20
/-!
More interestingly, a factorial function fact (e.g. `fun x => if (x == 0) then 1 else (fact (x-1) * x)`), can be written as.
Note that this is a recursive (non-terminating) definition. For every input value, the interpreter terminates, but the
definition itself is non-terminating. We use two tricks to make sure Lean accepts it. First, we use the auxiliary constructor
`Expr.delay` to delay its unfolding. Second, we add the annotation `decreasing_by sorry` which can be viwed as
"trust me, this recursive definition makes sense". Recall that `sorry` is an unsound axiom in Lean.
-/
def fact : Expr ctx (Ty.fn Ty.int Ty.int) :=
lam (ife (op (·==·) (var stop) (val 0))
(val 1)
(op (·*·) (delay fun _ => app fact (op (·-·) (var stop) (val 1))) (var stop)))
decreasing_by sorry
#eval fact.interp Env.nil 10

View File

@@ -0,0 +1,5 @@
(this example is rendered by Alectryon in the CI)
```lean
{{#include interp.lean}}
```

View File

@@ -0,0 +1,122 @@
/-!
# Palindromes
Palindromes are lists that read the same from left to right and from right to left.
For example, `[a, b, b, a]` and `[a, h, a]` are palindromes.
We use an inductive predicate to specify whether a list is a palindrome or not.
Recall that inductive predicates, or inductively defined propositions, are a convenient
way to specify functions of type `... → Prop`.
This example is a based on an example from the book "The Hitchhiker's Guide to Logical Verification".
-/
inductive Palindrome : List α Prop where
| nil : Palindrome []
| single : (a : α) Palindrome [a]
| sandwich : (a : α) Palindrome as Palindrome ([a] ++ as ++ [a])
/-!
The definition distinguishes three cases: (1) `[]` is a palindrome; (2) for any element
`a`, the singleton list `[a]` is a palindrome; (3) for any element `a` and any palindrome
`[b₁, . . ., bₙ]`, the list `[a, b₁, . . ., bₙ, a]` is a palindrome.
-/
/-!
We now prove that the reverse of a palindrome is a palindrome using induction on the inductive predicate `h : Palindrome as`.
-/
theorem palindrome_reverse (h : Palindrome as) : Palindrome as.reverse := by
induction h with
| nil => exact Palindrome.nil
| single a => exact Palindrome.single a
| sandwich a h ih => simp; exact Palindrome.sandwich _ ih
/-! If a list `as` is a palindrome, then the reverse of `as` is equal to itself. -/
theorem reverse_eq_of_palindrome (h : Palindrome as) : as.reverse = as := by
induction h with
| nil => rfl
| single a => rfl
| sandwich a h ih => simp [ih]
/-! Note that you can also easily prove `palindrome_reverse` using `reverse_eq_of_palindrome`. -/
example (h : Palindrome as) : Palindrome as.reverse := by
simp [reverse_eq_of_palindrome h, h]
/-!
Given a nonempty list, the function `List.last` returns its element.
Note that we use `(by simp)` to prove that `a₂ :: as ≠ []` in the recursive application.
-/
def List.last : (as : List α) as [] α
| [a], _ => a
| a₁::a₂:: as, _ => (a₂::as).last (by simp)
/-!
We use the function `List.last` to prove the following theorem that says that if a list `as` is not empty,
then removing the last element from `as` and appending it back is equal to `as`.
We use the attribute `@[simp]` to instruct the `simp` tactic to use this theorem as a simplification rule.
-/
@[simp] theorem List.dropLast_append_last (h : as []) : as.dropLast ++ [as.last h] = as := by
match as with
| [] => contradiction
| [a] => simp_all [last, dropLast]
| a₁ :: a₂ :: as =>
simp [last, dropLast]
exact dropLast_append_last (as := a₂ :: as) (by simp)
/-!
We now define the following auxiliary induction principle for lists using well-founded recursion on `as.length`.
We can read it as follows, to prove `motive as`, it suffices to show that: (1) `motive []`; (2) `motive [a]` for any `a`;
(3) if `motive as` holds, then `motive ([a] ++ as ++ [b])` also holds for any `a`, `b`, and `as`.
Note that the structure of this induction principle is very similar to the `Palindrome` inductive predicate.
-/
theorem List.palindrome_ind (motive : List α Prop)
(h₁ : motive [])
(h₂ : (a : α) motive [a])
(h₃ : (a b : α) (as : List α) motive as motive ([a] ++ as ++ [b]))
(as : List α)
: motive as :=
match as with
| [] => h₁
| [a] => h₂ a
| a₁::a₂::as' =>
have ih := palindrome_ind motive h₁ h₂ h₃ (a₂::as').dropLast
have : [a₁] ++ (a₂::as').dropLast ++ [(a₂::as').last (by simp)] = a₁::a₂::as' := by simp
this h₃ _ _ _ ih
termination_by _ as => as.length
/-!
We use our new induction principle to prove that if `as.reverse = as`, then `Palindrome as` holds.
Note that we use the `using` modifier to instruct the `induction` tactic to use this induction principle
instead of the default one for lists.
-/
theorem List.palindrome_of_eq_reverse (h : as.reverse = as) : Palindrome as := by
induction as using palindrome_ind
next => exact Palindrome.nil
next a => exact Palindrome.single a
next a b as ih =>
have : a = b := by simp_all
subst this
have : as.reverse = as := by simp_all
exact Palindrome.sandwich a (ih this)
/-!
We now define a function that returns `true` iff `as` is a palindrome.
The function assumes that the type `α` has decidable equality. We need this assumption
because we need to compare the list elements.
-/
def List.isPalindrome [DecidableEq α] (as : List α) : Bool :=
as.reverse = as
/-!
It is straightforward to prove that `isPalindrome` is correct using the previously proved theorems.
-/
theorem List.isPalindrome_correct [DecidableEq α] (as : List α) : as.isPalindrome Palindrome as := by
simp [isPalindrome]
exact Iff.intro (fun h => palindrome_of_eq_reverse h) (fun h => reverse_eq_of_palindrome h)
#eval [1, 2, 1].isPalindrome
#eval [1, 2, 3, 1].isPalindrome
example : [1, 2, 1].isPalindrome := rfl
example : [1, 2, 2, 1].isPalindrome := rfl
example : ![1, 2, 3, 1].isPalindrome := rfl

View File

@@ -0,0 +1,5 @@
(this example is rendered by Alectryon in the CI)
```lean
{{#include palindromes.lean}}
```

240
doc/examples/phoas.lean Normal file
View File

@@ -0,0 +1,240 @@
/-!
# Parametric Higher-Order Abstract Syntax
In contrast to first-order encodings, higher-order encodings avoid explicit modeling of variable identity.
Instead, the binding constructs of an object language (the language being
formalized) can be represented using the binding constructs of the meta language (the language in which the formalization is done).
The best known higher-order encoding is called higher-order abstract syntax (HOAS),
and we can start by attempting to apply it directly in Lean.
Remark: this example is based on an example in the book [Certified Programming with Dependent Types](http://adam.chlipala.net/cpdt/) by Adam Chlipala.
-/
/-!
Here is the definition of the simple type system for our programming language, a simply typed
lambda calculus with natural numbers as the base type.
-/
inductive Ty where
| nat
| fn : Ty Ty Ty
/-!
We can write a function to translate `Ty` values to a Lean type
— remember that types are first class, so can be calculated just like any other value.
We mark `Ty.denote` as `[reducible]` to make sure the typeclass resolution procedure can
unfold/reduce it. For example, suppose Lean is trying to synthesize a value for the instance
`Add (Ty.denote Ty.nat)`. Since `Ty.denote` is marked as `[reducible],
the typeclass resolution procedure can reduce `Ty.denote Ty.nat` to `Nat`, and use
the builtin instance for `Add Nat` as the solution.
Recall that the term `a.denote` is sugar for `denote a` where `denote` is the function being defined.
We call it the "dot notation".
-/
@[reducible] def Ty.denote : Ty Type
| nat => Nat
| fn a b => a.denote b.denote
/-!
With HOAS, each object language binding construct is represented with a function of
the meta language. Here is what we get if we apply that idea within an inductive definition
of term syntax. However a naive encondig in Lean fails to meet the strict positivity restrictions
imposed by the Lean kernel. An alternate higher-order encoding is parametric HOAS, as introduced by Washburn
and Weirich for Haskell and tweaked by Adam Chlipala for use in Coq. The key idea is to parameterize the
declaration by a type family `rep` standing for a "representation of variables."
-/
inductive Term' (rep : Ty Type) : Ty Type
| var : rep ty Term' rep ty
| const : Nat Term' rep .nat
| plus : Term' rep .nat Term' rep .nat Term' rep .nat
| lam : (rep dom Term' rep ran) Term' rep (.fn dom ran)
| app : Term' rep (.fn dom ran) Term' rep dom Term' rep ran
| «let» : Term' rep ty₁ (rep ty₁ Term' rep ty₂) Term' rep ty₂
/-!
Lean accepts this definition because our embedded functions now merely take variables as
arguments, instead of arbitrary terms. One might wonder whether there is an easy loophole
to exploit here, instantiating the parameter `rep` as term itself. However, to do that, we
would need to choose a variable representation for this nested mention of term, and so on
through an infinite descent into term arguments.
We write the final type of a closed term using polymorphic quantification over all possible
choices of `rep` type family
-/
open Ty (nat fn)
open Term'
namespace FirstTry
def Term (ty : Ty) := (rep : Ty Type) Term' rep ty
/-!
In the next two example, note how each is written as a function over a `rep` choice,
such that the specific choice has no impact on the structure of the term.
-/
def add : Term (fn nat (fn nat nat)) := fun rep =>
lam fun x => lam fun y => plus (var x) (var y)
def three_the_hard_way : Term nat := fun rep =>
app (app (add rep) (const 1)) (const 2)
end FirstTry
/-!
The argument `rep` does not even appear in the function body for `add`. How can that be?
By giving our terms expressive types, we allow Lean to infer many arguments for us. In fact,
we do not even need to name the `rep` argument! By using Lean implicit arguments and lambdas,
we can completely hide `rep` in these examples.
-/
def Term (ty : Ty) := {rep : Ty Type} Term' rep ty
def add : Term (fn nat (fn nat nat)) :=
lam fun x => lam fun y => plus (var x) (var y)
def three_the_hard_way : Term nat :=
app (app add (const 1)) (const 2)
/-!
It may not be at all obvious that the PHOAS representation admits the crucial computable
operations. The key to effective deconstruction of PHOAS terms is one principle: treat
the `rep` parameter as an unconstrained choice of which data should be annotated on each
variable. We will begin with a simple example, that of counting how many variable nodes
appear in a PHOAS term. This operation requires no data annotated on variables, so we
simply annotate variables with `Unit` values. Note that, when we go under binders in the
cases for `lam` and `let`, we must provide the data value to annotate on the new variable we
pass beneath. For our current choice of `Unit` data, we always pass `()`.
-/
def countVars : Term' (fun _ => Unit) ty Nat
| var h => 1
| const n => 0
| plus a b => countVars a + countVars b
| app f a => countVars f + countVars a
| lam b => countVars (b ())
| «let» a b => countVars a + countVars (b ())
/-! We can now easily prove that `add` has two variables by using reflexivity -/
example : countVars add = 2 :=
rfl
/-!
Here is another example, translating PHOAS terms into strings giving a first-order rendering.
To implement this translation, the key insight is to tag variables with strings, giving their names.
The function takes as an additional input `i` which is used to create variable names for binders.
We also use the string interpolation available in Lean. For example, `s!"x_{i}"` is expanded to
`"x_" ++ toString i`.
-/
def pretty (e : Term' (fun _ => String) ty) (i : Nat := 1) : String :=
match e with
| var s => s
| const n => toString n
| app f a => s!"({pretty f i} {pretty a i})"
| plus a b => s!"({pretty a i} + {pretty b i})"
| lam f =>
let x := s!"x_{i}"
s!"(fun {x} => {pretty (f x) (i+1)})"
| «let» a b =>
let x := s!"x_{i}"
s!"(let {x} := {pretty a i}; => {pretty (b x) (i+1)}"
#eval pretty three_the_hard_way
/-!
It is not necessary to convert to a different representation to support many common
operations on terms. For instance, we can implement substitution of terms for variables.
The key insight here is to tag variables with terms, so that, on encountering a variable, we
can simply replace it by the term in its tag. We will call this function initially on a term
with exactly one free variable, tagged with the appropriate substitute. During recursion,
new variables are added, but they are only tagged with their own term equivalents. Note
that this function squash is parameterized over a specific `rep` choice.
-/
def squash : Term' (Term' rep) ty Term' rep ty
| var e => e
| const n => const n
| plus a b => plus (squash a) (squash b)
| lam f => lam fun x => squash (f (.var x))
| app f a => app (squash f) (squash a)
| «let» a b => «let» (squash a) fun x => squash (b (.var x))
/-!
To define the final substitution function over terms with single free variables, we define
`Term1`, an analogue to Term that we defined before for closed terms.
-/
def Term1 (ty1 ty2 : Ty) := {rep : Ty Type} rep ty1 Term' rep ty2
/-!
Substitution is defined by (1) instantiating a `Term1` to tag variables with terms and (2)
applying the result to a specific term to be substituted. Note how the parameter `rep` of
`squash` is instantiated: the body of `subst` is itself a polymorphic quantification over `rep`,
standing for a variable tag choice in the output term; and we use that input to compute a
tag choice for the input term.
-/
def subst (e : Term1 ty1 ty2) (e' : Term ty1) : Term ty2 :=
squash (e e')
/-!
We can view `Term1` as a term with hole. In the following example,
`(fun x => plus (var x) (const 5))` can be viewed as the term `plus _ (const 5)` where
the hole `_` is instantiated by `subst` with `three_the_hard_way`
-/
#eval pretty <| subst (fun x => plus (var x) (const 5)) three_the_hard_way
/-!
One further development, which may seem surprising at first,
is that we can also implement a usual term denotation function,
when we tag variables with their denotations.
The attribute `[simp]` instructs Lean to always try to unfold `denote` applications when one applies
the `simp` tactic. We also say this is a hint for the Lean term simplifier.
-/
@[simp] def denote : Term' Ty.denote ty ty.denote
| var x => x
| const n => n
| plus a b => denote a + denote b
| app f a => denote f (denote a)
| lam f => fun x => denote (f x)
| «let» a b => denote (b (denote a))
example : denote three_the_hard_way = 3 :=
rfl
/-!
To summarize, the PHOAS representation has all the expressive power of more
standard encodings (e.g., using de Bruijn indices), and a variety of translations are actually much more pleasant to
implement than usual, thanks to the novel ability to tag variables with data.
-/
/-!
We now define the constant folding optimization that traverses a term if replaces subterms such as
`plus (const m) (const n)` with `const (n+m)`.
-/
@[simp] def constFold : Term' rep ty Term' rep ty
| var x => var x
| const n => const n
| app f a => app (constFold f) (constFold a)
| lam f => lam fun x => constFold (f x)
| «let» a b => «let» (constFold a) fun x => constFold (b x)
| plus a b =>
match constFold a, constFold b with
| const n, const m => const (n+m)
| a', b' => plus a' b'
/-!
The correctness of the `constFold` is proved using induction, case-analysis, and the term simplifier.
We prove all cases but the one for `plus` using `simp [*]`. This tactic instructs the term simplifier to
use hypotheses such as `a = b` as rewriting/simplications rules.
We use the `split` to break the nested `match` expression in the `plus` case into two cases.
The local variables `iha` and `ihb` are the induction hypotheses for `a` and `b`.
The modifier `←` in a term simplifier argument instructs the term simplier to use the equation as a rewriting rule in
the "reverse direction. That is, given `h : a = b`, `← h` instructs the term simplifier to rewrite `b` subterms to `a`.
-/
theorem constFold_sound (e : Term' Ty.denote ty) : denote (constFold e) = denote e := by
induction e with simp [*]
| plus a b iha ihb =>
split
next he₁ he₂ => simp [ iha, ihb, he₁, he₂]
next => simp [iha, ihb]

View File

@@ -0,0 +1,5 @@
(this example is rendered by Alectryon in the CI)
```lean
{{#include phoas.lean}}
```

119
doc/examples/tc.lean Normal file
View File

@@ -0,0 +1,119 @@
/-!
# A Certified Type Checker
In this example, we build a certified type checker for a simple expression
language.
Remark: this example is based on an example in the book [Certified Programming with Dependent Types](http://adam.chlipala.net/cpdt/) by Adam Chlipala.
-/
inductive Expr where
| nat : Nat Expr
| plus : Expr Expr Expr
| bool : Bool Expr
| and : Expr Expr Expr
/-!
We define a simple language of types using the inductive datatype `Ty`, and
its typing rules using the inductive predicate `HasType`.
-/
inductive Ty where
| nat
| bool
deriving DecidableEq
inductive HasType : Expr Ty Prop
| nat : HasType (.nat v) .nat
| plus : HasType a .nat HasType b .nat HasType (.plus a b) .nat
| bool : HasType (.bool v) .bool
| and : HasType a .bool HasType b .bool HasType (.and a b) .bool
/-!
We can easily show that if `e` has type `t₁` and type `t₂`, then `t₁` and `t₂` must be equal
by using the the `cases` tactic. This tactic creates a new subgoal for every constructor,
and automatically discharges unreachable cases. The tactic combinator `tac₁ <;> tac₂` applies
`tac₂` to each subgoal produced by `tac₁`. Then, the tactic `rfl` is used to close all produced
goals using reflexivity.
-/
theorem HasType.det (h₁ : HasType e t₁) (h₂ : HasType e t₂) : t₁ = t₂ := by
cases h₁ <;> cases h₂ <;> rfl
/-!
The inductive type `Maybe p` has two contructors: `found a h` and `unknown`.
The former contains an element `a : α` and a proof that `a` satisfies the predicate `p`.
The constructor `unknown` is used to encode "failure".
-/
inductive Maybe (p : α Prop) where
| found : (a : α) p a Maybe p
| unknown
/-!
We define a notation for `Maybe` that is similar to the builtin notation for the Lean builtin type `Subtype`.
-/
notation "{{ " x " | " p " }}" => Maybe (fun x => p)
/-!
The function `Expr.typeCheck e` returns a type `ty` and a proof that `e` has type `ty`,
or `unknown`.
Recall that, `def Expr.typeCheck ...` in Lean is notation for `namespace Expr def typeCheck ... end Expr`.
The term `.found .nat .nat` is sugar for `Maybe.found Ty.nat HasType.nat`. Lean can infer the namespaces using
the expected types.
-/
def Expr.typeCheck (e : Expr) : {{ ty | HasType e ty }} :=
match e with
| nat .. => .found .nat .nat
| bool .. => .found .bool .bool
| plus a b =>
match a.typeCheck, b.typeCheck with
| .found .nat h₁, .found .nat h₂ => .found .nat (.plus h₁ h₂)
| _, _ => .unknown
| and a b =>
match a.typeCheck, b.typeCheck with
| .found .bool h₁, .found .bool h₂ => .found .bool (.and h₁ h₂)
| _, _ => .unknown
theorem Expr.typeCheck_correct (h₁ : HasType e ty) (h₂ : e.typeCheck .unknown)
: e.typeCheck = .found ty h := by
revert h₂
cases typeCheck e with
| found ty' h' => intro; have := HasType.det h₁ h'; subst this; rfl
| unknown => intros; contradiction
/-!
Now, we prove that if `Expr.typeCheck e` returns `Maybe.unknown`, then forall `ty`, `HasType e ty` does not hold.
The notation `e.typeCheck` is sugar for `Expr.typeCheck e`. Lean can infer this because we explicitly said that `e` has type `Expr`.
The proof is by induction on `e` and case analysis. The tactic `rename_i` is used to to rename "inaccessible" variables.
We say a variable is inaccessible if it is introduced by a tactic (e.g., `cases`) or has been shadowed by another variable introduced
by the user. Note that the tactic `simp [typeCheck]` is applied to all goal generated by the `induction` tactic, and closes
the cases corresponding to the constructors `Expr.nat` and `Expr.bool`.
-/
theorem Expr.typeCheck_complete {e : Expr} : e.typeCheck = .unknown ¬ HasType e ty := by
induction e with simp [typeCheck]
| plus a b iha ihb =>
split
next => intros; contradiction
next ra rb hnp =>
-- Recall that `hnp` is a hypothesis generated by the `split` tactic
-- that asserts the previous case was not taken
intro h ht
cases ht with
| plus h₁ h₂ => exact hnp h₁ h₂ (typeCheck_correct h₁ (iha · h₁)) (typeCheck_correct h₂ (ihb · h₂))
| and a b iha ihb =>
split
next => intros; contradiction
next ra rb hnp =>
intro h ht
cases ht with
| and h₁ h₂ => exact hnp h₁ h₂ (typeCheck_correct h₁ (iha · h₁)) (typeCheck_correct h₂ (ihb · h₂))
/-!
Finally, we show that type checking for `e` can be decided using `Expr.typeCheck`.
-/
instance (e : Expr) (t : Ty) : Decidable (HasType e t) :=
match h' : e.typeCheck with
| .found t' ht' =>
if heq : t = t' then
isTrue (heq ht')
else
isFalse fun ht => heq (HasType.det ht ht')
| .unknown => isFalse (Expr.typeCheck_complete h')

5
doc/examples/tc.lean.md Normal file
View File

@@ -0,0 +1,5 @@
(this example is rendered by Alectryon in the CI)
```lean
{{#include tc.lean}}
```

4
doc/examples/test_single.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env bash
source ../../tests/common.sh
exec_check lean -j 0 -Dlinter.all=false "$f"

View File

@@ -219,7 +219,7 @@ def f2 (a b c : Bool) : Bool :=
#eval (1, 2)
def p : Nat × Bool := (1,
def p : Nat × Bool := (1, false)
section
variables (a b c : Nat) (p : Nat × bool)
@@ -419,33 +419,31 @@ Every computable definition in Lean is compiled to bytecode at definition time.
.. code-block:: lean
#reduce (λ x, x + 3) 5
#eval (λ x, x + 3) 5
#reduce (fun x => x + 3) 5
#eval (fun x => x + 3) 5
#reduce let x := 5 in x + 3
#eval let x := 5 in x + 3
#reduce let x := 5; x + 3
#eval let x := 5; x + 3
def f x := x + 3
#reduce f 5
#eval f 5
#reduce @nat.rec (λ n, Nat) (0 : Nat)
(λ n recval : Nat, recval + n + 1) (5 : Nat)
#eval @nat.rec (λ n, Nat) (0 : Nat)
(λ n recval : Nat, recval + n + 1) (5 : Nat)
#reduce @Nat.rec (λ n => Nat) (0 : Nat)
(λ n recval : Nat => recval + n + 1) (5 : Nat)
def g : Nat → Nat
| 0 := 0
| (n+1) := g n + n + 1
| 0 => 0
| (n+1) => g n + n + 1
#reduce g 5
#eval g 5
#eval g 50000
#eval g 5000
example : (λ x, x + 3) 5 = 8 := rfl
example : (λ x, f x) = f := rfl
example : (fun x => x + 3) 5 = 8 := rfl
example : (fun x => f x) = f := rfl
example (p : Prop) (h₁ h₂ : p) : h₁ = h₂ := rfl
Note: the combination of proof irrelevance and singleton ``Prop`` elimination in ι-reduction renders the ideal version of definitional equality, as described above, undecidable. Lean's procedure for checking definitional equality is only an approximation to the ideal. It is not transitive, as illustrated by the example below. Once again, this does not compromise the consistency or soundness of Lean; it only means that Lean is more conservative in the terms it recognizes as well typed, and this does not cause problems in practice. Singleton elimination will be discussed in greater detail in [Inductive Types](inductive.md).

214
doc/flake.lock generated Normal file
View File

@@ -0,0 +1,214 @@
{
"nodes": {
"alectryon": {
"flake": false,
"locked": {
"lastModified": 1654613606,
"narHash": "sha256-IGCn1PzTyw8rrwmyWUiw3Jo/dyZVGkMslnHYW7YB8yk=",
"owner": "Kha",
"repo": "alectryon",
"rev": "c3b16f650665745e1da4ddfcc048d3bd639f71d5",
"type": "github"
},
"original": {
"owner": "Kha",
"ref": "typeid",
"repo": "alectryon",
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1644229661,
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"lean": {
"inputs": {
"flake-utils": "flake-utils",
"lean-stage0": "lean-stage0",
"lean4-mode": "lean4-mode",
"nix": "nix",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 0,
"narHash": "sha256-AfBkKX6Ahb9YbZke+eWLmsUk1Z9BwdJ1CpIoPY8Msx8=",
"path": "../.",
"type": "path"
},
"original": {
"path": "../.",
"type": "path"
}
},
"lean-stage0": {
"locked": {
"lastModified": 0,
"narHash": "sha256-3K/43lSW4WIHNG+HHVKCD1odS63mHuaQ4ueHyTIkcls=",
"owner": "leanprover",
"repo": "lean4",
"rev": "0000000000000000000000000000000000000000",
"type": "github"
},
"original": {
"owner": "leanprover",
"repo": "lean4",
"type": "github"
}
},
"lean4-mode": {
"flake": false,
"locked": {
"lastModified": 1647694750,
"narHash": "sha256-0rV61KhevG9IAjZDN2Ts2VS65fiUAPAezbf282u7yy8=",
"owner": "leanprover",
"repo": "lean4-mode",
"rev": "c016c7aeee92564836355083664c49ed57024427",
"type": "github"
},
"original": {
"owner": "leanprover",
"repo": "lean4-mode",
"type": "github"
}
},
"leanInk": {
"flake": false,
"locked": {
"lastModified": 1655643380,
"narHash": "sha256-sVc2LNQ0/D2DsuRGWfsP/sVsi//jTsoWMVwTeYwS/wQ=",
"owner": "leanprover",
"repo": "LeanInk",
"rev": "0a160d91458c1873937449a7c78d25b34b8686df",
"type": "github"
},
"original": {
"owner": "leanprover",
"repo": "LeanInk",
"type": "github"
}
},
"lowdown-src": {
"flake": false,
"locked": {
"lastModified": 1633514407,
"narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
"owner": "kristapsdz",
"repo": "lowdown",
"rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
"type": "github"
},
"original": {
"owner": "kristapsdz",
"repo": "lowdown",
"type": "github"
}
},
"mdBook": {
"flake": false,
"locked": {
"lastModified": 1644567966,
"narHash": "sha256-fqdb2AUAMmi54vfa2qOF7VMFvN3rNku8/kUh1YEW86g=",
"owner": "leanprover",
"repo": "mdBook",
"rev": "b7a9bc48e9881087cac684d0c6c2c0a3583417e8",
"type": "github"
},
"original": {
"owner": "leanprover",
"repo": "mdBook",
"type": "github"
}
},
"nix": {
"inputs": {
"lowdown-src": "lowdown-src",
"nixpkgs": "nixpkgs",
"nixpkgs-regression": "nixpkgs-regression"
},
"locked": {
"lastModified": 1648022028,
"narHash": "sha256-HtwmifW6STPcym+3uJ4YavgTKTYVIoiQHg3f0wXOm+Q=",
"owner": "NixOS",
"repo": "nix",
"rev": "98ce1a21b7d959c5575fac566c8699e91703a9f7",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1632864508,
"narHash": "sha256-d127FIvGR41XbVRDPVvozUPQ/uRHbHwvfyKHwEt5xFM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "82891b5e2c2359d7e58d08849e4c89511ab94234",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-21.05-small",
"type": "indirect"
}
},
"nixpkgs-regression": {
"locked": {
"lastModified": 1643052045,
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
},
"original": {
"id": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1648219316,
"narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"alectryon": "alectryon",
"flake-utils": [
"lean",
"flake-utils"
],
"lean": "lean",
"leanInk": "leanInk",
"mdBook": "mdBook"
}
}
},
"root": "root",
"version": 7
}

95
doc/flake.nix Normal file
View File

@@ -0,0 +1,95 @@
{
description = "Lean documentation";
inputs.lean.url = path:../.;
inputs.flake-utils.follows = "lean/flake-utils";
inputs.mdBook = {
url = github:leanprover/mdBook;
flake = false;
};
inputs.alectryon = {
url = github:Kha/alectryon/typeid;
flake = false;
};
inputs.leanInk = {
url = github:leanprover/LeanInk;
flake = false;
};
outputs = inputs@{ self, ... }: inputs.flake-utils.lib.eachDefaultSystem (system:
with inputs.lean.packages.${system}; with nixpkgs;
let
doc-src = lib.sourceByRegex ../. ["doc.*" "tests(/lean(/beginEndAsMacro.lean)?)?"];
in {
packages = rec {
lean-mdbook = mdbook.overrideAttrs (drv: rec {
name = "lean-${mdbook.name}";
src = inputs.mdBook;
cargoDeps = drv.cargoDeps.overrideAttrs (_: {
inherit src;
outputHash = "sha256-5cAV8tOU3R1cPubseetURDQOzKyoo4485wD5IgeJUhQ=";
});
doCheck = false;
});
book = stdenv.mkDerivation {
name ="lean-doc";
src = doc-src;
buildInputs = [ lean-mdbook ];
buildCommand = ''
mkdir $out
# necessary for `additional-css`...?
cp -r --no-preserve=mode $src/doc/* .
# overwrite stub .lean.md files
cp -r ${examples}/* .
mdbook build -d $out
'';
};
# We use a separate derivation instead of `checkPhase` so we can push it but not `doc` to the binary cache
test = stdenv.mkDerivation {
name ="lean-doc-test";
src = doc-src;
buildInputs = [ lean-mdbook stage1.Lean.lean-package strace ];
patchPhase = ''
cd doc
patchShebangs test
'';
buildPhase = ''
mdbook test
touch $out
'';
dontInstall = true;
};
leanInk = (buildLeanPackage {
name = "Main";
src = inputs.leanInk;
deps = [ (buildLeanPackage {
name = "LeanInk";
src = inputs.leanInk;
}) ];
executableName = "leanInk";
linkFlags = ["-rdynamic"];
}).executable;
alectryon = python3Packages.buildPythonApplication {
name = "alectryon";
src = inputs.alectryon;
propagatedBuildInputs =
[ leanInk lean-all ] ++
# https://github.com/cpitclaudel/alectryon/blob/master/setup.cfg
(with python3Packages; [ pygments dominate beautifulsoup4 docutils ]);
doCheck = false;
};
examples = let
renderLean = name: file: runCommandNoCC "${name}.md" { buildInputs = [ alectryon ]; } ''
mkdir -p $out/examples
alectryon --frontend lean4+markup ${file} --backend webpage -o $out/examples/${name}.md
'';
ents = builtins.readDir ./examples;
inputs = lib.filterAttrs (n: t: builtins.match ".*\.lean" n != null && t == "regular") ents;
outputs = lib.mapAttrs (n: _: renderLean n ./examples/${n}) inputs;
in
outputs // symlinkJoin { name = "examples"; paths = lib.attrValues outputs; };
doc = book;
};
defaultPackage = self.packages.${system}.doc;
});
}

7
doc/fplean.md Normal file
View File

@@ -0,0 +1,7 @@
Functional Programming in Lean
=======================
The goal of [this book](https://leanprover.github.io/functional_programming_in_lean/) is to be an accessible introduction to using Lean 4 as a programming language.
It should be useful both to people who want to use Lean as a general-purpose programming language and to mathematicians who want to develop larger-scale proof automation but do not have a background in functional programming.
It does not assume any background with functional programming, though it's probably not a good first book on programming in general.
New content will be added once per month until it's done.

View File

@@ -46,6 +46,25 @@ partial def g (x : Nat) (p : Nat -> Bool) : Nat :=
In the previous example, `g x p` only terminates if there is a `y >= x` such that `p y` returns `true`.
Of course, `g 0 (fun x => false)` never terminates.
However, the use of `partial` is restricted to functions whose return type is not empty so the soundness
of the system is not compromised.
```lean,ignore
partial def loop? : α := -- failed to compile partial definition 'loop?', failed to
loop? -- show that type is inhabited and non empty
partial def loop [Inhabited α] : α := -- compiles
loop
example : True := -- accepted
loop
example : False :=
loop -- failed to synthesize instance Inhabited False
```
If we were able to partially define `loop?`, we could prove `False` with it.
# Lambda expressions
A lambda expression is an unnamed function.
@@ -70,28 +89,25 @@ def twice (f : Nat -> Nat) (x : Nat) : Nat :=
# Syntax sugar for simple lambda expressions
Simple functions can be defined using parentheses and `.` (or `·`) as a placeholder.
Simple functions can be defined using parentheses and `·` as a placeholder.
```lean
#check (. + 1)
-- fun a => a + 1
#check (· + 1)
-- fun a => a + 1
#check (2 - .)
#check (2 - ·)
-- fun a => 2 - a
#eval [1, 2, 3, 4, 5].foldl (. * .) 1
#eval [1, 2, 3, 4, 5].foldl (· * ·) 1
-- 120
def h (x y z : Nat) :=
x + y + z
#check (h . 1 .)
#check (h · 1 ·)
-- fun a b => h a 1 b
#eval [(1, 2), (3, 4), (5, 6)].map (·.1)
-- [1, 3, 5]
```
In the previous example, the term `(·.1)` is syntax sugar for `fun x => x.1`. Note that, the ASCII version `(..1)`
is not supported because `..` is a reserved symbol.
In the previous example, the term `(·.1)` is syntax sugar for `fun x => x.1`.
# Pipelining
@@ -111,14 +127,14 @@ In contrast, the backward pipeline `<|` operator takes an argument and a functio
These operators are useful for minimizing the number of parentheses.
```lean
def add1Times3FilterEven (xs : List Nat) :=
List.filter (. % 2 == 0) (List.map (. * 3) (List.map (. + 1) xs))
List.filter (· % 2 == 0) (List.map (· * 3) (List.map (· + 1) xs))
#eval add1Times3FilterEven [1, 2, 3, 4]
-- [6, 12]
-- Define the same function using pipes
def add1Times3FilterEven' (xs : List Nat) :=
xs |> List.map (. + 1) |> List.map (. * 3) |> List.filter (. % 2 == 0)
xs |> List.map (· + 1) |> List.map (· * 3) |> List.filter (· % 2 == 0)
#eval add1Times3FilterEven' [1, 2, 3, 4]
-- [6, 12]
@@ -127,7 +143,7 @@ Lean also supports the operator `|>.` which combines forward pipeline `|>` opera
```lean
-- Define the same function using pipes
def add1Times3FilterEven'' (xs : List Nat) :=
xs.map (. + 1) |>.map (. * 3) |>.filter (. % 2 == 0)
xs.map (· + 1) |>.map (· * 3) |>.filter (· % 2 == 0)
#eval add1Times3FilterEven'' [1, 2, 3, 4]
-- [6, 12]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
doc/images/install_elan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -1,3 +1,3 @@
# Inductive Types
TODO
[Theorem Proving in Lean](https://leanprover.github.io/theorem_proving_in_lean4/inductive_types.html) has a chapter about inductive datatypes.

View File

@@ -14,7 +14,7 @@ to separate the elements of a list, and in the lambda expression itself. We now
as an example, `fun x => x` is the identity function. One may still use the symbol `λ` as a shorthand for `fun`.
The lambda expression notation has many new features that are not supported in Lean 3.
* Pattern matching
## Pattern matching
In Lean 4, one can easily create new notation that abbreviates commonly used idioms. One of them is a
`fun` followed by a `match`. In the following examples, we define a few functions using `fun`+`match` notation.
@@ -39,7 +39,7 @@ def Sum.str : Option Nat → String :=
# end ex1
```
* Implicit lambdas
## Implicit lambdas
In Lean 3 stdlib, we find many [instances](https://github.com/leanprover/lean/blob/master/library/init/category/reader.lean#L39) of the dreadful `@`+`_` idiom.
It is often used when we the expected type is a function type with implicit arguments,
@@ -83,7 +83,7 @@ def id5 : {α : Type} → αα :=
# end ex2
```
* Sugar for simple functions
## Sugar for simple functions
In Lean 3, we can create simple functions from infix operators by using parentheses. For example, `(+1)` is sugar for `fun x, x + 1`. In Lean 4, we generalize this notation using `·` As a placeholder. Here are a few examples:
@@ -230,11 +230,10 @@ restriction imposed by ordinary type theory. Metadefinitions may also use unsafe
The keyword `meta` has been currently removed from Lean 4. However, we may re-introduce it in the future,
but with a much more limited purpose: marking meta code that should not be included in the executables produced by Lean.
The keywords `axiom` and `constant` are not equivalent in Lean 4. In Lean 4, `constant` is used to define
an opaque definition. Here are two simple examples:
The keyword `constant` has been deleted in Lean 4, and `axiom` should be used instead. In Lean 4, the new command `opaque` is used to define an opaque definition. Here are two simple examples:
```lean
# namespace meta1
constant x : Nat := 1
opaque x : Nat := 1
-- The following example will not type check since `x` is opaque
-- example : x = 1 := rfl
@@ -244,11 +243,11 @@ constant x : Nat := 1
-- When no value is provided, the elaborator tries to build one automatically for us
-- using the `Inhabited` type class
constant y : Nat
opaque y : Nat
# end meta1
```
We can instruct Lean to use a foreign function as the implementation for any constant or definition
We can instruct Lean to use a foreign function as the implementation for any definition
using the attribute `@[extern "foreign_function"]`. It is the user's responsibility to ensure the
foreign implementation is correct.
However, a user mistake here will only impact the code generated by Lean, and
@@ -336,3 +335,34 @@ partial def f (x : Nat) : IO Unit := do
#eval f 98
# end partial1
```
## Library changes
These are changes to the library which may trip up Lean 3 users:
- `Option` and `List` are no longer monads. Instead there is `OptionM`. This was done to avoid some performance traps. For example `o₁ <|> o₂` where `o₁ o₂ : Option α` will evaluate both `o₁` and `o₂` even if `o₁` evaluates to `some x`. This can be a problem if `o₂` requires a lot of compute to evaluate. A zulip discussion on this design choice is [here](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Option.20do.20notation.20regression.3F).
## Style changes
Coding style changes have also been made:
- Term constants and variables are now `lowerCamelCase` rather than `snake_case`
- Type constants are now `UpperCamelCase`, eg `Nat`, `List`. Type variables are still lower case greek letters. Functors are still lower case latin `(m : Type → Type) [Monad m]`.
- When defining typeclasses, prefer not to use "has". Eg `ToString` or `Add` instead of `HasToString` or `HasAdd`.
- Prefer `return` to `pure` in monad expressions.
- Pipes `<|` are preferred to dollars `$` for function application.
- Declaration bodies should always be indented:
```lean
inductive Hello where
| foo
| bar
structure Point where
x : Nat
y : Nat
def Point.addX : Point → Point → Nat :=
fun { x := a, .. } { x := b, .. } => a + b
```
- In structures and typeclass definitions, prefer `where` to `:=` and don't surround fields with parentheses. (Shown in `Point` above)

View File

@@ -158,7 +158,7 @@ Output:
[Elab.definition.body] binderterm.quot : Lean.ParserDescr :=
Lean.ParserDescr.node `Lean.Parser.Term.quot 1024
(Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol "`(binderterm|")
(Lean.ParserDescr.binary `andthen (Lean.ParserDescr.unary `incQuotDepth (Lean.ParserDescr.cat `binderterm 0))
(Lean.ParserDescr.binary `andthen (Lean.ParserDescr.cat `binderterm 0)
(Lean.ParserDescr.symbol ")")))
-/
```

View File

@@ -46,9 +46,8 @@ For example, on an AMD Ryzen 9 `make` takes 00:04:55, whereas `make -j 10`
takes 00:01:38. Your results may vary depending on the speed of your hard
drive.
To install the build, see [Dev setup using
elan](../dev/index.md#dev-setup-using-elan).
You should not usually run `make install` after a successful build.
See [Dev setup using elan](../dev/index.md#dev-setup-using-elan) on how to properly set up your editor to use the correct stage depending on the source directory.
Useful CMake Configuration Settings
-----------------------------------

View File

@@ -18,8 +18,7 @@ the stdlib.
## Installing dependencies
[The official webpage of MSYS2][msys2] provides one-click installers.
Once installed, you should run the "MSYS2 MinGW 64-bit shell" from the start menu.
(The one that runs `mingw64.exe`)
Once installed, you should run the "MSYS2 MinGW 64-bit shell" from the start menu (the one that runs `mingw64.exe`).
Do not run "MSYS2 MSYS" instead!
MSYS2 has a package management system, [pacman][pacman], which is used in Arch Linux.
@@ -74,6 +73,11 @@ The following linux command will do that:
cp $(ldd lean.exe | cut -f3 -d' ' | grep mingw) .
```
However, if you plan to use this build to compile lean programs
to executable binaries using `lake build` in normal Windows command
prompt outside of msys2 environment you will also need to add a windows
version clang to your path.
## Trouble shooting
**-bash: gcc: command not found**

View File

@@ -10,7 +10,7 @@ Follow the setup in the link above; to open the Lean shell inside a Lean checkou
$ nix-shell -A nix
```
On top of the local and remote Nix cache, it helps to we do still rely on CCache as well to make C/C++ build steps incremental, which are atomic steps from Nix's point of view.
On top of the local and remote Nix cache, we do still rely on CCache as well to make C/C++ build steps incremental, which are atomic steps from Nix's point of view.
To enable CCache, add the following line to the config file mentioned in the setup:
```bash
extra-sandbox-paths = /nix/var/cache/ccache
@@ -35,7 +35,7 @@ The `stage1.` part in each command is optional:
```bash
nix build .#test # run tests for stage 1
nix build . # build stage 1
nix build # dito
nix build # ditto
```
## Build Process Description
@@ -52,11 +52,14 @@ This is because modules are discovered not from a directory listing anymore but
As in the standard Nix setup.
After adding `src/` as an LSP workspace, it should automatically fall back to using stage 0 in there.
Note that the UX of `emacs/vscode-dev` is quite different from the Make-based setup regarding the compilation of dependencies:
Note that the UX of `{emacs,vscode}-dev` is quite different from the Make-based setup regarding the compilation of dependencies:
there is no mutable directory incrementally filled by the build that we could point the editor at for .olean files.
Instead, `emacs-dev` will gather the individual dependency outputs from the Nix store when checking a file -- and build them on the fly when necessary.
However, it will only ever load changes saved to disk, not ones opened in other buffers.
The absence of a mutable output directory also means that the Lean server will not automatically pick up `.ilean` metadata from newly compiled files.
Instead, you can run `nix run .#link-ilean` to symlink the `.ilean` tree of the stdlib state at that point in time to `src/build/lib`, where the server should automatically find them.
## Other Fun Stuff to Do with Nix
Open Emacs with Lean set up from an arbitrary commit (without even cloning Lean beforehand... if your Nix is new enough):
@@ -86,7 +89,7 @@ nix run .#HEAD-as-stage0.emacs-dev&
```
To run `nix build` on the second stage outside of the second editor, use
```bash
nix build .#stage0-from-input
nix build .#stage0-from-input --override-input lean-stage0 .\?rev=$(git rev-parse HEAD)
```
This setup will inadvertently change your `flake.lock` file, which you can revert when you are done.

View File

@@ -0,0 +1,58 @@
inductive Arith : Type
| add : Arith Arith Arith -- e + f
| mul : Arith Arith Arith -- e * f
| int : Int Arith -- constant
| symbol : String Arith -- variable
declare_syntax_cat arith
syntax num : arith -- int for Arith.int
syntax str : arith -- strings for Arith.symbol
syntax:60 arith:60 "+" arith:61 : arith -- Arith.add
syntax:70 arith:70 "*" arith:71 : arith -- Arith.mul
syntax "(" arith ")" : arith -- parenthesized expressions
-- auxiliary notation for translating `arith` into `term`
syntax "`[Arith| " arith "]" : term
macro_rules
| `(`[Arith| $s:str]) => `(Arith.symbol $s)
| `(`[Arith| $num:num]) => `(Arith.int $num)
| `(`[Arith| $x:arith + $y:arith]) => `(Arith.add `[Arith| $x] `[Arith| $y])
| `(`[Arith| $x:arith * $y:arith]) => `(Arith.mul `[Arith| $x] `[Arith| $y])
| `(`[Arith| ($x:arith)]) => `(`[Arith| $x])
#check `[Arith| "x" * "y"] -- mul
-- Arith.mul (Arith.symbol "x") (Arith.symbol "y")
#check `[Arith| "x" + "y"] -- add
-- Arith.add (Arith.symbol "x") (Arith.symbol "y")
#check `[Arith| "x" + 20] -- symbol + int
-- Arith.add (Arith.symbol "x") (Arith.int 20)
#check `[Arith| "x" + "y" * "z"] -- precedence
-- Arith.add (Arith.symbol "x") (Arith.mul (Arith.symbol "y") (Arith.symbol "z"))
#check `[Arith| "x" * "y" + "z"] -- precedence
-- Arith.add (Arith.mul (Arith.symbol "x") (Arith.symbol "y")) (Arith.symbol "z")
#check `[Arith| ("x" + "y") * "z"] -- parentheses
-- Arith.mul (Arith.add (Arith.symbol "x") (Arith.symbol "y")) (Arith.symbol "z")
syntax ident : arith
macro_rules
| `(`[Arith| $x:ident]) => `(Arith.symbol $(Lean.quote (toString x.getId)))
#check `[Arith| x] -- Arith.symbol "x"
def xPlusY := `[Arith| x + y]
#print xPlusY -- def xPlusY : Arith := Arith.add (Arith.symbol "x") (Arith.symbol "y")
syntax "<[" term "]>" : arith -- escape for embedding terms into `Arith`
macro_rules
| `(`[Arith| <[ $e:term ]>]) => pure e
#check `[Arith| <[ xPlusY ]> + z] -- Arith.add xPlusY (Arith.symbol "z")

View File

@@ -0,0 +1,134 @@
# Arithmetic as an embedded domain-specific language
Let's parse another classic grammar, the grammar of arithmetic expressions with
addition, multiplication, integers, and variables. In the process, we'll learn
how to:
- Convert identifiers such as `x` into strings within a macro.
- add the ability to "escape" the macro context from within the macro. This is useful to interpret identifiers with their _original_ meaning (predefined values)
instead of their new meaning within a macro (treat as a symbol).
Let's begin with the simplest thing possible. We'll define an AST, and use operators `+` and `*` to denote
building an arithmetic AST.
Here's the AST that we will be parsing:
```lean,ignore
{{#include metaprogramming-arith.lean:1:5}}
```
We declare a syntax category to describe the grammar that we will be parsing.
See that we control the precedence of `+` and `*` by writing `syntax:50` for addition and `syntax:60` for multiplication,
indicating that multiplication binds tighter than addition (higher the number, tighter the binding).
This allows us to declare _precedence_ when defining new syntax.
```lean,ignore
{{#include metaprogramming-arith.lean:7:13}}
```
Further, if we look at `syntax:60 arith:60 "+" arith:61 : arith`, the
precedence declarations at `arith:60 "+" arith:61` conveys that the left
argument must have precedence at least `60` or greater, and the right argument
must have precedence at least`61` or greater. Note that this forces left
associativity. To understand this, let's compare two hypothetical parses:
```
-- syntax:60 arith:60 "+" arith:61 : arith -- Arith.add
-- a + b + c
(a:60 + b:61):60 + c
a + (b:60 + c:61):60
```
In the parse tree of `a + (b:60 + c:61):60`, we see that the right argument `(b + c)` is given the precedence `60`. However,
the rule for addition expects the right argument to have a precedence of **at least** 61, as witnessed by the `arith:61` at
the right-hand-side of `syntax:60 arith:60 "+" arith:61 : arith`. Thus, the rule `syntax:60 arith:60 "+" arith:61 : arith`
ensures that addition is left associative.
Since addition is declared arguments of precedence `60/61` and multiplication with `70/71`, this causes multiplication to bind
tighter than addition. Once again, let's compare two hypothetical parses:
```
-- syntax:60 arith:60 "+" arith:61 : arith -- Arith.add
-- syntax:70 arith:70 "*" arith:71 : arith -- Arith.mul
-- a * b + c
a * (b:60 + c:61):60
(a:70 * b:71):70 + c
```
While parsing `a * (b + c)`, `(b + c)` is assigned a precedence `60` by the addition rule. However, multiplication expects
the right argument to have precedence **at least** 71. Thus, this parse is invalid. In contrast, `(a * b) + c` assigns
a precedence of `70` to `(a * b)`. This is compatible with addition which expects the left argument to have precedence
**at least `60` ** (`70` is greater than `60`). Thus, the string `a * b + c` is parsed as `(a * b) + c`.
For more details, please look at the [Lean manual on syntax extensions](../syntax.md#notations-and-precedence).
To go from strings into `Arith`, we define a macro to
translate the syntax category `arith` into an `Arith` inductive value that
lives in `term`:
```lean,ignore
{{#include metaprogramming-arith.lean:15:16}}
```
Our macro rules perform the "obvious" translation:
```lean,ignore
{{#include metaprogramming-arith.lean:18:23}}
```
And some examples:
```lean,ignore
{{#include metaprogramming-arith.lean:25:41}}
```
Writing variables as strings, such as `"x"` gets old; wouldn't it be so much
prettier if we could write `x * y`, and have the macro translate this into `Arith.mul (Arith.Symbol "x") (Arith.mul "y")`?
We can do this, and this will be our first taste of manipulating macro variables --- we'll use `x.getId` instead of directly evaluating `$x`.
We also write a macro rule for `Arith|` that translates an identifier into
a string, using `$(Lean.quote (toString x.getId))`:
```lean,ignore
{{#include metaprogramming-arith.lean:43:46}}
```
Let's test and see that we can now write expressions such as `x * y` directly instead of having to write `"x" * "y"`:
```lean,ignore
{{#include metaprogramming-arith.lean:48:51}}
```
We now show an unfortunate consequence of the above definitions. Suppose we want to build `(x + y) + z`.
Since we already have defined `xPlusY` as `x + y`, perhaps we should reuse it! Let's try:
```lean,ignore
#check `[Arith| xPlusY + z] -- Arith.add (Arith.symbol "xPlusY") (Arith.symbol "z")
```
Whoops, that didn't work! What happened? Lean treats `xPlusY` _itself_ as an identifier! So we need to add some syntax
to be able to "escape" the `Arith|` context. Let's use the syntax `<[ $e:term ]>` to mean: evaluate `$e` as a real term,
not an identifier. The macro looks like follows:
```lean,ignore
{{#include metaprogramming-arith.lean:53:56}}
```
Let's try our previous example:
```lean,ignore
{{#include metaprogramming-arith.lean:58:58}}
```
Perfect!
In this tutorial, we expanded on the previous tutorial to parse a more
realistic grammar with multiple levels of precedence, how to parse identifiers directly
within a macro, and how to provide an escape from within the macro context.
#### Full code listing
```lean
{{#include metaprogramming-arith.lean}}
```

View File

@@ -1,10 +0,0 @@
# Metaprogramming
Macros are a language feature that allows writing code that writes other code (metaprogramming).
In Lean 4, macros are used pervasively. So much so that core language features such as `do` notation
is implemented via macros! As a language user, macros are useful to easily
embed domain-specific languages and to generate code at compile-time, to name a few uses.
## References
- [Hygenic Macro Expansion for Theorem Proving Languages](https://arxiv.org/abs/2001.10490)

View File

@@ -20,7 +20,7 @@ this operator should be translated to after the arrow `=>`.
The precedence is a natural number describing how "tightly" an
operator binds to its arguments, encoding the order of operations. We
can make this more precise by looking at the commands above unfold to:
can make this more precise by looking at what the commands above unfold to:
```lean
notation:65 lhs:65 " + " rhs:66 => HAdd.hAdd lhs rhs

81
doc/pygments.css Normal file
View File

@@ -0,0 +1,81 @@
/* Pygments stylesheet generated by Alectryon (style=None) */
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll, .code .hll { background-color: #ffffcc }
.highlight .c, .code .c { color: #555753; font-style: italic } /* Comment */
.highlight .err, .code .err { color: #a40000; border: 1px solid #cc0000 } /* Error */
.highlight .g, .code .g { color: #000000 } /* Generic */
.highlight .k, .code .k { color: #8f5902 } /* Keyword */
.highlight .l, .code .l { color: #2e3436 } /* Literal */
.highlight .n, .code .n { color: #000000 } /* Name */
.highlight .o, .code .o { color: #000000 } /* Operator */
.highlight .x, .code .x { color: #2e3436 } /* Other */
.highlight .p, .code .p { color: #000000 } /* Punctuation */
.highlight .ch, .code .ch { color: #555753; font-weight: bold; font-style: italic } /* Comment.Hashbang */
.highlight .cm, .code .cm { color: #555753; font-style: italic } /* Comment.Multiline */
.highlight .cp, .code .cp { color: #3465a4; font-style: italic } /* Comment.Preproc */
.highlight .cpf, .code .cpf { color: #555753; font-style: italic } /* Comment.PreprocFile */
.highlight .c1, .code .c1 { color: #555753; font-style: italic } /* Comment.Single */
.highlight .cs, .code .cs { color: #3465a4; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd, .code .gd { color: #a40000 } /* Generic.Deleted */
.highlight .ge, .code .ge { color: #000000; font-style: italic } /* Generic.Emph */
.highlight .gr, .code .gr { color: #a40000 } /* Generic.Error */
.highlight .gh, .code .gh { color: #a40000; font-weight: bold } /* Generic.Heading */
.highlight .gi, .code .gi { color: #4e9a06 } /* Generic.Inserted */
.highlight .go, .code .go { color: #000000; font-style: italic } /* Generic.Output */
.highlight .gp, .code .gp { color: #8f5902 } /* Generic.Prompt */
.highlight .gs, .code .gs { color: #000000; font-weight: bold } /* Generic.Strong */
.highlight .gu, .code .gu { color: #000000; font-weight: bold } /* Generic.Subheading */
.highlight .gt, .code .gt { color: #000000; font-style: italic } /* Generic.Traceback */
.highlight .kc, .code .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */
.highlight .kd, .code .kd { color: #4e9a06; font-weight: bold } /* Keyword.Declaration */
.highlight .kn, .code .kn { color: #4e9a06; font-weight: bold } /* Keyword.Namespace */
.highlight .kp, .code .kp { color: #204a87 } /* Keyword.Pseudo */
.highlight .kr, .code .kr { color: #8f5902 } /* Keyword.Reserved */
.highlight .kt, .code .kt { color: #204a87 } /* Keyword.Type */
.highlight .ld, .code .ld { color: #2e3436 } /* Literal.Date */
.highlight .m, .code .m { color: #2e3436 } /* Literal.Number */
.highlight .s, .code .s { color: #ad7fa8 } /* Literal.String */
.highlight .na, .code .na { color: #c4a000 } /* Name.Attribute */
.highlight .nb, .code .nb { color: #75507b } /* Name.Builtin */
.highlight .nc, .code .nc { color: #204a87 } /* Name.Class */
.highlight .no, .code .no { color: #ce5c00 } /* Name.Constant */
.highlight .nd, .code .nd { color: #3465a4; font-weight: bold } /* Name.Decorator */
.highlight .ni, .code .ni { color: #c4a000; text-decoration: underline } /* Name.Entity */
.highlight .ne, .code .ne { color: #cc0000 } /* Name.Exception */
.highlight .nf, .code .nf { color: #a40000 } /* Name.Function */
.highlight .nl, .code .nl { color: #3465a4; font-weight: bold } /* Name.Label */
.highlight .nn, .code .nn { color: #000000 } /* Name.Namespace */
.highlight .nx, .code .nx { color: #000000 } /* Name.Other */
.highlight .py, .code .py { color: #000000 } /* Name.Property */
.highlight .nt, .code .nt { color: #a40000 } /* Name.Tag */
.highlight .nv, .code .nv { color: #ce5c00 } /* Name.Variable */
.highlight .ow, .code .ow { color: #8f5902 } /* Operator.Word */
.highlight .w, .code .w { color: #d3d7cf; text-decoration: underline } /* Text.Whitespace */
.highlight .mb, .code .mb { color: #2e3436 } /* Literal.Number.Bin */
.highlight .mf, .code .mf { color: #2e3436 } /* Literal.Number.Float */
.highlight .mh, .code .mh { color: #2e3436 } /* Literal.Number.Hex */
.highlight .mi, .code .mi { color: #2e3436 } /* Literal.Number.Integer */
.highlight .mo, .code .mo { color: #2e3436 } /* Literal.Number.Oct */
.highlight .sa, .code .sa { color: #ad7fa8 } /* Literal.String.Affix */
.highlight .sb, .code .sb { color: #ad7fa8 } /* Literal.String.Backtick */
.highlight .sc, .code .sc { color: #ad7fa8; font-weight: bold } /* Literal.String.Char */
.highlight .dl, .code .dl { color: #ad7fa8 } /* Literal.String.Delimiter */
.highlight .sd, .code .sd { color: #ad7fa8 } /* Literal.String.Doc */
.highlight .s2, .code .s2 { color: #ad7fa8 } /* Literal.String.Double */
.highlight .se, .code .se { color: #ad7fa8; font-weight: bold } /* Literal.String.Escape */
.highlight .sh, .code .sh { color: #ad7fa8; text-decoration: underline } /* Literal.String.Heredoc */
.highlight .si, .code .si { color: #ce5c00 } /* Literal.String.Interpol */
.highlight .sx, .code .sx { color: #ad7fa8 } /* Literal.String.Other */
.highlight .sr, .code .sr { color: #ad7fa8 } /* Literal.String.Regex */
.highlight .s1, .code .s1 { color: #ad7fa8 } /* Literal.String.Single */
.highlight .ss, .code .ss { color: #8f5902 } /* Literal.String.Symbol */
.highlight .bp, .code .bp { color: #5c35cc } /* Name.Builtin.Pseudo */
.highlight .fm, .code .fm { color: #a40000 } /* Name.Function.Magic */
.highlight .vc, .code .vc { color: #ce5c00 } /* Name.Variable.Class */
.highlight .vg, .code .vg { color: #ce5c00; text-decoration: underline } /* Name.Variable.Global */
.highlight .vi, .code .vi { color: #ce5c00 } /* Name.Variable.Instance */
.highlight .vm, .code .vm { color: #ce5c00 } /* Name.Variable.Magic */
.highlight .il, .code .il { color: #2e3436 } /* Literal.Number.Integer.Long */

View File

@@ -1,36 +1,51 @@
# Quickstart
These instructions will walk you through setting up Lean using the "basic" setup and VS Code as the editor.
See [Setup](./setup.md) for other ways and more details on setting up Lean.
See [Setup](./setup.md) for other ways, supported platforms, and more details on setting up Lean.
See quick [walkthrough demo video](https://www.youtube.com/watch?v=yZo6k48L0VY).
1. Install the latest Lean 4 nightly through [`elan`](https://github.com/leanprover/elan): in any bash-compatible shell, run
```sh
curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh -s -- --default-toolchain leanprover/lean4:nightly
```
On Windows, instead run in `cmd`
```sh
curl -O --location https://raw.githubusercontent.com/leanprover/elan/master/elan-init.ps1
powershell -f elan-init.ps1 --default-toolchain leanprover/lean4:nightly
del elan-init.ps1
```
See the [elan repo](https://github.com/leanprover/elan) for other installation options and details.
1. Install [VS Code](https://code.visualstudio.com/).
1. Open VS Code and install the `lean4` extension.
1. Launch VS Code and install the `lean4` extension.
![installing the vscode-lean4 extension](images/code-ext.png)
1. Create a new file with the extension `.lean` and add the following code:
```lean
import Leanpkg
1. Create a new file using "File > New Text File" (`Ctrl+N`). Click the `Select a language` prompt, type in `lean4`, and hit ENTER. You should see the following popup:
![elan](images/install_elan.png)
Click the "Install Lean using Elan" button. You should see some progress output like this:
#eval Leanpkg.leanVersionString
```
You should get a syntax-highlighted file with a "Lean Infoview" on the right that tells you the installed Lean version when placing your cursor on the last line.
info: syncing channel updates for 'nightly'
info: latest update on nightly, lean version nightly-2021-12-05
info: downloading component 'lean'
```
1. While it is installing, you can paste the following Lean program into the new file:
```lean
#eval Lean.versionString
```
When the installation has finished, the Lean Language Server should start automatically and you should get syntax-highlighting and a "Lean Infoview" popping up on the right. You will see the output of the `#eval` statement when
you place your cursor at the end of the statement.
![successful setup](images/code-success.png)
1. You are set up! Try opening a Lean folder containing a package file `leanpkg.toml`. You can create your own packages using `leanpkg init` on the command line.
Packages **have** to be opened using "File > Open Folder..." for imports to work.
Saved changes are visible in other files after running "Lean 4: Refresh File Dependencies" (`Ctrl+Shift+X`).
You are set up!
## Create a Lean Project
You can now create a Lean project in a new folder. Run `lake init foo` from "View > Terminal" to create a package, followed by `lake build` to get an executable version of your Lean program.
On Linux/macOS, you first have to follow the instructions printed by the Lean installation or log out and in again for the Lean executables to be available in you terminal.
Note: Packages **have** to be opened using "File > Open Folder..." for imports to work.
Saved changes are visible in other files after running "Lean 4: Refresh File Dependencies" (`Ctrl+Shift+X`).
## Troubleshooting
**The InfoView says "Waiting for Lean server to start..." forever.**
Check that the VS Code Terminal is not showing some installation errors from `elan`.
If that doesn't work, try also running the VS Code command `Developer: Reload Window`.

View File

@@ -1,3 +1,29 @@
# Supported Platforms
### Tier 1
Platforms built & tested by our CI, available as nightly & stable releases via elan (see above)
* x86-64 Linux with glibc 2.27+
* x86-64 macOS 10.15+
* x86-64 Windows 10+
### Tier 2
Platforms cross-compiled but not tested by our CI, available as nightly & stable releases
Releases may be silently broken due to the lack of automated testing.
Issue reports and fixes are welcome.
* aarch64 Linux with glibc 2.27+
* aarch64 (M1) macOS
<!--
### Tier 3
Platforms that are known to work from manual testing, but do not come with CI or official releases
-->
# Setting Up Lean
There are currently two ways to set up a Lean 4 development environment:
@@ -21,25 +47,29 @@ $ elan default leanprover/lean4:nightly
$ elan override set leanprover/lean4:stable
```
### `leanpkg`
### `lake`
Lean 4 comes with a basic package manager, `leanpkg`.
Use `leanpkg init Foo` to initialize a Lean package `Foo` in the current directory, and `leanpkg build` to typecheck and build it as well as all its dependencies; call `leanpkg help` to learn about further commands.
The general directory structure of a package `Foo` is
Lean 4 comes with a package manager named `lake`.
Use `lake init foo` to initialize a Lean package `foo` in the current directory, and `lake build` to typecheck and build it as well as all its dependencies. Use `lake help` to learn about further commands.
The general directory structure of a package `foo` is
```sh
leanpkg.toml # package configuration
Foo.lean # main file, import via `import Foo`
lakefile.lean # package configuration
lean-toolchain # specifies the lean version to use
Foo.lean # main file, import via `import Foo`
Foo/
A.lean # further files, import via e.g. `import Foo.A`
A/... # further nesting
build/ # `leanpkg` output directory
A.lean # further files, import via e.g. `import Foo.A`
A/... # further nesting
build/ # `lake` build output directory
```
After running `lake build` you will see a binary named `./build/bin/foo` and when you run it you should see the output:
```
Hello, world!
```
Note however that producing native binaries and libraries (`leanpkg build bin/lb`) currently depends on `make` and an external C compiler for recursive compilation.
It has been tested on Windows by installing these tools using [MSYS2](https://www.msys2.org/), but [MinGW](http://www.mingw.org/) or WSL should work, too.
### Editing
Lean implements the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) that can be used for interactive development in [Emacs](https://github.com/leanprover/lean4/tree/master/lean4-mode/README.md), [VS Code](https://github.com/leanprover-community/vscode-lean4), and possibly other editors.
Lean implements the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) that can be used for interactive development in [Emacs](https://github.com/leanprover/lean4-mode), [VS Code](https://github.com/leanprover-community/vscode-lean4), and possibly other editors.
Changes must be saved to be visible in other files, which must then be invalidated using an editor command (see links above).
@@ -77,7 +107,7 @@ From a Lean shell, run
$ nix flake new mypkg -t github:leanprover/lean4
```
to create a new Lean package in directory `mypkg` using the latest commit of Lean 4.
Such packages follow the same directory layout as described in the basic setup above, except for a `leanpkg.toml`/`lakefile.lean` replaced by a `flake.nix` file set up so you can run Nix commands on it, for example:
Such packages follow the same directory layout as described in the basic setup above, except for a `lakefile.lean` replaced by a `flake.nix` file set up so you can run Nix commands on it, for example:
```bash
$ nix build # build package and all dependencies
$ nix build .#executable # compile `main` definition into executable (after you've added one)
@@ -112,5 +142,5 @@ nix-collect-garbage
```
This will remove everything not reachable from "GC roots" such as the `./result` symlink created by `nix build`.
Note that the package information in `flake.nix` is currently completely independent from `leanpkg.toml` used in the basic setup.
Note that the package information in `flake.nix` is currently completely independent from `lakefile.lean` used in the basic setup.
Unifying the two formats is TBD.

View File

@@ -217,4 +217,11 @@ def msg2 : MessageExt where
## Updating structure fields
TODO
Structure fields can be updated using `{ <struct-val> with <field> := <new-value>, ... }`:
```lean
# structure Point (α : Type u) where
# x : α
# y : α
def incrementX (p : Point Nat) : Point Nat := { p with x := p.x + 1 }
```

View File

@@ -1,14 +1,15 @@
# Syntax Extensions
[Lean's syntax](lexical_structure.md) can be extended and customized
by users at every level, ranging from basic "mixfix" notations to
custom elaborators. In fact, all builtin syntax is parsed and
Lean's syntax can be extended and customized
by users at every level, ranging from [basic "mixfix" notations](./notation.md)
over [macro transformers](./macro_overview.md) to
[type-aware elaborators](./elaborators.md). In fact, all builtin syntax is parsed and
processed using the same mechanisms and APIs open to users. In this
section, we will describe and explain the various extension points.
Significant syntax extensions already builtin into Lean such as the
[`do` notation](./do.md) are described in subsections.
While [introducing new notations](./notation.md) is a relatively rare feature in
While introducing new syntax is a relatively rare feature in
programming languages and sometimes even frowned upon because of its
potential to obscure code, it is an invaluable tool in formalization
for expressing established conventions and notations of the respective
@@ -17,14 +18,3 @@ to factor out common boilerplate code into (well-behaved) macros and
to embed entire custom domain specific languages (DSLs) to textually
encode subproblems efficiently and readably can be of great benefit to
both programmers and proof engineers alike.
## Syntax and Macros
## Elaborators
TODO. See [Lean Together 2021: Metaprogramming in Lean
4](https://youtu.be/hxQ1vvhYN_U) for an overview as well [the
continuation](https://youtu.be/hxQ1vvhYN_U) about tactic programming.
For more information on antiquotations, see also §4.1 of [Beyond
Notations: Hygienic Macro Expansion for Theorem Proving
Languages](https://arxiv.org/pdf/2001.10490.pdf#page=11).

23
doc/syntax_example.lean Normal file
View File

@@ -0,0 +1,23 @@
inductive Dyck : Type where
| round : Dyck Dyck -- ( <inner> )
| curly : Dyck Dyck -- { <inner> }
| leaf : Dyck
-- declare Dyck grammar parse trees
declare_syntax_cat brack
syntax "(" brack ")" : brack
syntax "{" brack "}" : brack
syntax "end" : brack
-- notation for translating `brack` into `term`
syntax "`[Dyck| " brack "]" : term
-- rules to translate Dyck grammar into inductive value of type Dyck
macro_rules
| `(`[Dyck| end]) => `(Dyck.leaf)
| `(`[Dyck| ($b)]) => `(Dyck.round `[Dyck| $b]) -- recurse
| `(`[Dyck| {$b}]) => `(Dyck.curly `[Dyck| $b]) -- recurse
-- tests
#check `[Dyck| end] -- Dyck.leaf
#check `[Dyck| {(end)}] -- Dyck.curl (Dyck.round Dyck.leaf)

View File

@@ -4,19 +4,19 @@ Let's look at how to use macros to extend the Lean 4 parser and embed a language
This language accepts strings given by the [BNF grammar](https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form)
```
Dyck :=
Dyck ::=
"(" Dyck ")"
| "{" Dyck '}'
| "End"
| "{" Dyck "}"
| end
```
We begin by defining an inductive data type of the grammar we wish to parse:
```lean,ignore
inductive Dyck: Type :=
| Round : Dyck -> Dyck -- ( <inner> )
| Flower : Dyck -> Dyck -- { <inner> }
| End : Dyck
inductive Dyck : Type where
| round : Dyck Dyck -- ( <inner> )
| curly : Dyck Dyck -- { <inner> }
| leaf : Dyck
```
We begin by declaring a _syntax category_ using the `declare_syntax_cat <category>` command.
@@ -29,10 +29,10 @@ declare_syntax_cat brack
Next, we specify the grammar using the `syntax <parse rule>` command:
```lean,ignore
syntax "End" : brack
syntax "end" : brack
```
The above means that the string "End" lives in syntax category `brack`.
The above means that the token "end" lives in syntax category `brack`.
Similarly, we declare the rules `"(" Dyck ")"` and `"{" Dyck "}"` using the rules:
@@ -42,44 +42,32 @@ syntax "{" brack "}" : brack
```
Finally, we need a way to build _Lean 4 terms_ from this grammar -- that is, we must translate out of this
grammar into a `Dyck` value, which is a Lean 4 term. For this, we create a piece of syntax,
called `fromBrack% brack : term`, which receives a `brack` and produces a `term`.
grammar into a `Dyck` value, which is a Lean 4 term. For this, we create a new kind of "quotation" that
consumes syntax in `brack` and produces a `term`.
```lean,ignore
-- auxiliary notation for translating `brack` into `term`
syntax "fromBrack% " brack : term
syntax "`[Dyck| " brack "]" : term
```
To specify the transformation rules, we use `macro_rules` to declare how the syntax `fromBrack% <brack>`
To specify the transformation rules, we use `macro_rules` to declare how the syntax `` `[Dyck| <brack>] ``
produces terms. This is written using a pattern-matching style syntax, where the left-hand side
declares the pattern to be matched, and the right-hand side declares the production. Syntax placeholders (antiquotations)
declares the syntax pattern to be matched, and the right-hand side declares the production. Syntax placeholders (antiquotations)
are introduced via the `$<var-name>` syntax. The right-hand side is
an arbitrary Lean term that we are producing.
```lean,ignore
macro_rules
| `(fromBrack% End) => `(Dyck.End)
| `(fromBrack% ( $b )) => `(Dyck.Round (fromBrack% $b)) -- recurse
| `(fromBrack% { $b }) => `(Dyck.Flower (fromBrack% $b)) -- recurse
| `(`[Dyck| end]) => `(Dyck.leaf)
| `(`[Dyck| ($b)]) => `(Dyck.round `[Dyck| $b]) -- recurse
| `(`[Dyck| {$b}]) => `(Dyck.curly `[Dyck| $b]) -- recurse
```
```lean,ignore
def bar : Dyck := fromBrack% End
#print bar
/-
def bar : Dyck :=
Dyck.End
-/
def foo : Dyck := fromBrack% {(End)}
#print foo
/-
Dyck.Flower (Dyck.Round (Dyck.End))
-/
#check `[Dyck| end] -- Dyck.leaf
#check `[Dyck| {(end)}] -- Dyck.curl (Dyck.round Dyck.leaf)
```
In summary, we've seen:
- How to declare a syntax category for the Dyck grammar.
- How to specify parse trees of this grammar using `syntax`
@@ -87,41 +75,6 @@ In summary, we've seen:
The full program listing is given below:
```lean
inductive Dyck: Type :=
| Round : Dyck -> Dyck -- ( <inner> )
| Flower : Dyck -> Dyck -- { <inner> }
| End : Dyck
-- | declare Dyck grammar parse trees
declare_syntax_cat brack
syntax "End" : brack
syntax "(" brack ")" : brack
syntax "{" brack "}" : brack
-- auxiliary notation for translating `brack` into `term`
syntax "fromBrack% " brack : term
-- | rules to translate dyck grammar into inductive value of type Dyck.
macro_rules
| `(fromBrack% End) => `(Dyck.End)
| `(fromBrack% ( $b )) => `(Dyck.Round (fromBrack% $b)) -- recurse
| `(fromBrack% { $b }) => `(Dyck.Flower (fromBrack% $b)) -- recurse
-- | tests
def bar : Dyck := fromBrack% End
#print bar
/-
def bar : Dyck :=
Dyck.End
-/
def foo : Dyck := fromBrack% {(End)}
#print foo
/-
Dyck.Flower (Dyck.Round Dyck.End)
-/
{{#include syntax_example.lean}}
```

4
doc/syntax_examples.md Normal file
View File

@@ -0,0 +1,4 @@
# Syntax Metaprogramming Examples
- [Balanced Parentheses](./syntax_example.md)
- [Arithmetic DSL](./metaprogramming-arith.md)

View File

@@ -10,6 +10,7 @@ Save [`lstlean.tex`](https://raw.githubusercontent.com/leanprover/lean4/master/d
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{listings}
\usepackage{amssymb}
\usepackage{color}
\definecolor{keywordcolor}{rgb}{0.7, 0.1, 0.1} % red

View File

@@ -193,6 +193,50 @@ TODO
TODO
## Split
The `split` tactic can be used to split the cases of an if-then-else or
match into new subgoals, which can then be discharged individually.
```lean
def addMoreIfOdd (n : Nat) := if n % 2 = 0 then n + 1 else n + 2
/- Examine each branch of the conditional to show that the result
is always positive -/
example (n : Nat) : 0 < addMoreIfOdd n := by
simp only [addMoreIfOdd]
split
next => exact Nat.zero_lt_succ _
next => exact Nat.zero_lt_succ _
```
```lean
def binToChar (n : Nat) : Option Char :=
match n with
| 0 => some '0'
| 1 => some '1'
| _ => none
example (n : Nat) : (binToChar n).isSome -> n = 0 n = 1 := by
simp only [binToChar]
split
next => exact fun _ => Or.inl rfl
next => exact fun _ => Or.inr rfl
next => intro h; cases h
/- Hypotheses about previous cases can be accessesd by assigning them a
name, like `ne_zero` below. Information about the matched term can also
be preserved using the `generalizing` tactic: -/
example (n : Nat) : (n = 0) -> (binToChar n = some '0') := by
simp only [binToChar]
split
case h_1 => intro _; rfl
case h_2 => intro h; cases h
/- Here, we can introduce `n ≠ 0` and `n ≠ 1` this case assumes
neither of the previous cases matched. -/
case h_3 ne_zero _ => intro eq_zero; exact absurd eq_zero ne_zero
```
## Dependent pattern matching
The `match-with` expression implements dependent pattern matching. You can use it to create concise proofs.
@@ -202,7 +246,7 @@ inductive Mem : α → List α → Prop where
| head (a : α) (as : List α) : Mem a (a::as)
| tail (a b : α) (bs : List α) : Mem a bs Mem a (b::bs)
infix:50 "" => Mem
infix:50 (priority := high) "" => Mem
theorem mem_split {a : α} {as : List α} (h : a as) : s t, as = s ++ a :: t :=
match a, as, h with
@@ -219,7 +263,7 @@ Here is a similar proof using the tactic DSL.
# inductive Mem : α List α Prop where
# | head (a : α) (as : List α) : Mem a (a::as)
# | tail (a b : α) (bs : List α) : Mem a bs Mem a (b::bs)
# infix:50 "" => Mem
# infix:50 (priority := high) "" => Mem
theorem mem_split {a : α} {as : List α} (h : a as) : s t, as = s ++ a :: t := by
match a, as, h with
| _, _, Mem.head a bs => exists []; exists bs; rfl
@@ -237,7 +281,7 @@ Here is a similar proof that uses the `induction` tactic instead of recursion.
# inductive Mem : α List α Prop where
# | head (a : α) (as : List α) : Mem a (a::as)
# | tail (a b : α) (bs : List α) : Mem a bs Mem a (b::bs)
# infix:50 "" => Mem
# infix:50 (priority := high) "" => Mem
theorem mem_split {a : α} {as : List α} (h : a as) : s t, as = s ++ a :: t := by
induction as with
| nil => cases h
@@ -258,7 +302,7 @@ discriminant. Later, we show how to create more complex automation using macros.
# inductive Mem : α List α Prop where
# | head (a : α) (as : List α) : Mem a (a::as)
# | tail (a b : α) (bs : List α) : Mem a bs Mem a (b::bs)
# infix:50 "" => Mem
# infix:50 (priority := high) "" => Mem
macro "obtain " p:term " from " d:term : tactic =>
`(tactic| match $d:term with | $p:term => ?_)
@@ -313,13 +357,13 @@ You can use `let rec` to write local recursive functions. We lifted it to the ta
and you can use it to create proofs by induction.
```lean
theorem length_replicate {α} (n : Nat) (a : α) : (List.replicate n a).length = n := by
theorem length_replicateTR {α} (n : Nat) (a : α) : (List.replicateTR n a).length = n := by
let rec aux (n : Nat) (as : List α)
: (List.replicate.loop a n as).length = n + as.length := by
: (List.replicateTR.loop a n as).length = n + as.length := by
match n with
| 0 => rw [Nat.zero_add]; rfl
| n+1 =>
show List.length (List.replicate.loop a n (a::as)) = Nat.succ n + as.length
show List.length (List.replicateTR.loop a n (a::as)) = Nat.succ n + as.length
rw [aux n, List.length_cons, Nat.add_succ, Nat.succ_add]
exact aux n []
```
@@ -328,14 +372,14 @@ You can also introduce auxiliary recursive declarations using `where` clause aft
Lean converts them into a `let rec`.
```lean
theorem length_replicate {α} (n : Nat) (a : α) : (List.replicate n a).length = n :=
theorem length_replicateTR {α} (n : Nat) (a : α) : (List.replicateTR n a).length = n :=
loop n []
where
loop n as : (List.replicate.loop a n as).length = n + as.length := by
loop n as : (List.replicateTR.loop a n as).length = n + as.length := by
match n with
| 0 => rw [Nat.zero_add]; rfl
| n+1 =>
show List.length (List.replicate.loop a n (a::as)) = Nat.succ n + as.length
show List.length (List.replicateTR.loop a n (a::as)) = Nat.succ n + as.length
rw [loop n, List.length_cons, Nat.add_succ, Nat.succ_add]
```

View File

@@ -54,7 +54,7 @@ def g (c : Bool) (x : Nat) : Nat :=
```
In the following example, we use the macro `dbg_trace` to demonstrate
that the Lean runtime caches the value computed by a `Thunk`.
We remark that the macro `dbg_trace` should be use for debugging purposes
We remark that the macro `dbg_trace` should be used for debugging purposes
only.
```lean
def add1 (x : Nat) : Nat :=

View File

@@ -77,9 +77,9 @@ theorem twiceAdd2 (a : Nat) : twice (fun x => x + 2) a = a + 4 :=
-- until they are identical.
rfl
-- `(. + 2)` is syntax sugar for `(fun x => x + 2)`. The parentheses + `.` notation
-- `(· + 2)` is syntax sugar for `(fun x => x + 2)`. The parentheses + `·` notation
-- is useful for defining simple anonymous functions.
#eval twice (. + 2) 10
#eval twice (· + 2) 10
-- Enumerated types are a special case of inductive types in Lean,
-- which we will learn about later.

5
doc/tpil.md Normal file
View File

@@ -0,0 +1,5 @@
Theorem Proving in Lean
=======================
We strongly encourage you to read the book [Theorem Proving in Lean](https://leanprover.github.io/theorem_proving_in_lean4/title_page.html).
Many Lean users consider it to be the Lean Bible.

View File

@@ -1,245 +0,0 @@
## Arithmetic as an embedded domain-specific language
Let's parse another classic grammar, the grammar of arithmetic expressions with
addition, multiplication, integers, and variables. In the process, we'll learn
how to:
- Convert identifiers such as `x` into strings within a macro.
- add the ability to "escape" the macro context from within the macro. This is useful to interpret identifiers with their _original_ meaning (predefined values)
instead of their new meaning within a macro (treat as a symbol).
Let's begin with the simplest thing possible. We'll define an AST, and use operators `+` and `*` to denote
building an arithmetic AST.
Here's the AST that we will be parsing:
```lean,ignore
-- example on parsing arith language via macros
inductive Arith : Type where
| add : Arith → Arith → Arith -- e + f
| mul : Arith → Arith → Arith -- e * f
| int : Int → Arith -- constant
| symbol : String → Arith -- variable
```
We declare a syntax category to describe the grammar that we will be parsing.
See that we control the precedence of `+` and `*` by writing `syntax:50` for addition and `syntax:60` for multiplication,
indicating that multiplication binds tighter than addition (higher the number, tighter the binding).
This allows us to declare _precedence_ when defining new syntax.
```lean,ignore
declare_syntax_cat arith
syntax num : arith -- int for Arith.int
syntax str : arith -- strings for Arith.symbol
syntax:60 arith:60 "+" arith:61 : arith -- Arith.add
syntax:70 arith:70 "*" arith:71 : arith -- Arith.mul
syntax "(" arith ")" : arith -- bracketed expressions
```
Further, if we look at `syntax:60 arith:60 "+" arith:61 : arith`, the
precedence declarations at `arith:60 "+" arith:61` conveys that the left
argument must have precedence at least `60` or greater, and the right argument
must have precedence at least`61` or greater. Note that this forces left
associativity. To understand this, let's compare two hypothetical parses:
```
-- syntax:60 arith:60 "+" arith:61 : arith -- Arith.add
-- a + b + c
(a:60 + b:61):60 + c
a + (b:60 + c:61):60
```
In the parse tree of `a + (b:60 + c:61):60`, we see that the right argument `(b + c)` is given the precedence `60`. However,
the rule for addition expects the right argument to have a precedence of **at least** 61, as witnessed by the `arith:61` at
the right-hand-side of `syntax:60 arith:60 "+" arith:61 : arith`. Thus, the rule `syntax:60 arith:60 "+" arith:61 : arith`
ensures that addition is left associative.
Since addition is declared arguments of precedence `60/61` and multiplication with `70/71`, this causes multiplication to bind
tighter than addition. Once again, let's compare two hypothetical parses:
```
-- syntax:60 arith:60 "+" arith:61 : arith -- Arith.add
-- syntax:70 arith:70 "*" arith:71 : arith -- Arith.mul
-- a * b + c
a * (b:60 + c:61):60
(a:70 * b:71):70 + c
```
While parsing `a * (b + c)`, `(b + c)` is assigned a precedence `60` by the addition rule. However, multiplication expects
the right argument to have precedence **at least** 71. Thus, this parse is invalid. In contrast, `(a * b) + c` assigns
a precedence of `70` to `(a * b)`. This is compatible with addition which expects the left argument to have precedence
**at least `60` ** (`70` is greater than `60`). Thus, the string `a * b + c` is parsed as `(a * b) + c`.
For more details, please look at the [Lean manual on syntax extensions](../syntax.md#notations-and-precedence).
To go from strings into `Arith`, We define a macro to
translate the syntax category `arith` into an `Arith` inductive value that
lives in `term`:
```lean,ignore
-- auxiliary notation for translating `arith` into `term`
syntax "`[Arith| " arith "]" : term
```
Our macro rules perform the "obvious" translation:
```lean,ignore
macro_rules
| `(`[Arith| $s:strLit ]) => `(Arith.symbol $s)
| `(`[Arith| $num:numLit ]) => `(Arith.int $num)
| `(`[Arith| $x:arith + $y:arith ]) => `(Arith.add `[Arith| $x] `[Arith| $y])
| `(`[Arith| $x:arith * $y:arith ]) => `(Arith.mul `[Arith| $x] `[Arith| $y])
| `(`[Arith| ($x:arith) ]) => `(`[Arith| $x ])
```
And some examples:
```lean,ignore
#check `[Arith| "x" * "y"] -- Arith.mul (Arith.symbol "x") (Arith.symbol "y") : Arith
#check `[Arith| "x" + "y"] -- add
-- Arith.add (Arith.symbol "x") (Arith.symbol "y")
#check `[Arith| "x" + 20] -- symbol + int
-- Arith.add (Arith.symbol "x") (Arith.int 20)
#check `[Arith| "x" + "y" * "z" ] -- precedence
Arith.add (Arith.symbol "x") (Arith.mul (Arith.symbol "y") (Arith.symbol "z"))
--
#check `[Arith| "x" * "y" + "z"] -- precedence
-- Arith.add (Arith.mul (Arith.symbol "x") (Arith.symbol "y")) (Arith.symbol "z")
#check `[Arith| ("x" + "y") * "z"] -- brackets
-- Arith.mul (Arith.add (Arith.symbol "x") (Arith.symbol "y")) (Arith.symbol "z")
```
Writing variables as strings, such as `"x"` gets old; Wouldn't it be so much
prettier if we could write `x * y`, and have the macro translate this into `Arith.mul (Arith.Symbol "x") (Arith.mul "y")`?
We can do this, and this will be our first taste of manipulating macro variables --- we'll use `x.getId` instead of directly evaluating `$x`.
We also write a macro rule for `Arith|` that translates an identifier into
a string, using `$(Lean.quote (toString x.getId))`. (TODO: explain what
`Lean.quote` does):
```lean,ignore
syntax ident : arith
macro_rules
| `(`[Arith| $x:ident]) => `(Arith.symbol $(Lean.quote (toString x.getId)))
```
Let's test and see that we can now write expressions such as `x * y` directly instead of having to write `"x" * "y"`:
```lean,ignore
#check `[Arith| x ] -- Arith.symbol "x"
#check `[Arith| x + y] -- Arith.add (Arith.symbol "x") (Arith.symbol "y")
```
We now show an unfortunate consequence of the above definitions. Suppose we want to build `(x + y) + z)`.
Since we already have defined `x_plus_y` as `x + y`, perhaps we should reuse it! Let's try:
```lean,ignore
#check `[Arith| x_plus_y + z] --Arith.add (Arith.symbol "x_plus_y") (Arith.symbol "z")
```
Whoops, that didn't work! What happened? Lean treats `x_plus_y` _itself_ as an identifier! So we need to add some syntax
to be able to "escape" the `Arith|` context. Let's use the syntax `<[ $e:term ]>` to mean: evaluate `$e` as a real term,
not an identifier. The macro looks like follows:
```lean,ignore
syntax "<[" term "]>" : arith -- escape for embedding terms into `Arith`
macro_rules
| `(`[Arith| <[ $e:term ]> ]) => e
```
Let's try our previous example:
```lean,ignore
#check `[Arith| <[ x_plus_y ]>] -- x_plus_y
```
Perfect!
In this tutorial, we expanded on the previous tutorial to parse a more
realistic grammar with multiple levels of precedence, how to parse identifiers directly
within a macro, and how to provide an escape from within the macro context.
#### Full code listing
```lean
-- example on parsing arith language via macros
inductive Arith: Type
| add : Arith → Arith → Arith -- e + f
| mul : Arith → Arith → Arith -- e * f
| int : Int → Arith -- constant
| symbol : String → Arith -- variable
declare_syntax_cat arith
syntax num : arith -- int for Arith.int
syntax str : arith -- strings for Arith.symbol
syntax:60 arith:60 "+" arith:61 : arith -- Arith.add
syntax:70 arith:70 "*" arith:71 : arith -- Arith.mul
syntax "(" arith ")" : arith -- bracketed expressions
-- auxiliary notation for translating `arith` into `term`
syntax "`[Arith| " arith "]" : term
macro_rules
| `(`[Arith| $s:strLit ]) => `(Arith.symbol $s )
| `(`[Arith| $num:numLit ]) => `(Arith.int $num )
| `(`[Arith| $x:arith + $y:arith ]) => `(Arith.add `[Arith| $x] `[Arith| $y] )
| `(`[Arith| $x:arith * $y:arith ]) => `(Arith.mul `[Arith| $x] `[Arith| $y] )
| `(`[Arith| ($x:arith) ]) => `(`[Arith| $x ])
def foo :=
#check `[Arith| "x" * "y" ] -- mul
-- Arith.mul (Arith.symbol "x") (Arith.symbol "y")
def bar :=
#check `[Arith| "x" + "y"] -- add
-- Arith.add (Arith.symbol "x") (Arith.symbol "y")
def baz :=
#check `[Arith| "x" + 20] -- symbol + int
-- Arith.add (Arith.symbol "x") (Arith.int 20)
def quux_left :=
#check `[Arith| "x" + "y" * "z" ] -- precedence
-- Arith.add (Arith.symbol "x") (Arith.mul (Arith.symbol "y") (Arith.symbol "z"))
def quux_right :=
#check `[Arith| "x" * "y" + "z"] -- precedence
-- Arith.add (Arith.mul (Arith.symbol "x") (Arith.symbol "y")) (Arith.symbol "z")
def quuz :=
#check `[Arith| ("x" + "y") * "z"] -- brackets
-- Arith.mul (Arith.add (Arith.symbol "x") (Arith.symbol "y")) (Arith.symbol "z")
syntax ident : arith
macro_rules
| `(`[Arith| $x:ident]) => `(Arith.symbol $(Lean.quote (toString x.getId)))
#check `[Arith| x ] -- Arith.symbol "x"
#check `[Arith| x + y] -- Arith.add (Arith.symbol "x") (Arith.symbol "y")
#check `[Arith| x_plus_y + z] -- Arith.add (Arith.symbol "x_plus_y") (Arith.symbol "z")
syntax "<[" term "]>" : arith -- escape for embedding terms into `Arith`
macro_rules
| `(`[Arith| <[ $e:term ]> ]) => e
#check `[Arith| <[ x_plus_y ]>] -- x_plus_y
```

View File

@@ -76,7 +76,7 @@ you can declare an (anonymous) instance stating that if `a` has addition, then `
has addition:
```lean
instance [Add a] : Add (Array a) where
add x y := Array.zipWith x y (. + .)
add x y := Array.zipWith x y (· + ·)
#eval Add.add #[1, 2] #[3, 4]
-- #[4, 6]
@@ -157,31 +157,6 @@ export Inhabited (default)
-- true
# end Ex
```
Sometimes we want to think of the default element of a type as being an *arbitrary* element, whose specific value should not play a role in our proofs.
For that purpose, we can write ``arbitrary`` instead of ``default``. We define ``arbitrary`` as an *opaque* constant.
Opaque constants are never unfolded by the type checker.
```lean
# namespace Ex
# export Inhabited (default)
theorem defNatEq0 : (default : Nat) = 0 :=
rfl
constant arbitrary [Inhabited a] : a :=
Inhabited.default
-- theorem arbitraryNatEq0 : (arbitrary : Nat) = 0 :=
-- rfl
/-
error: type mismatch
rfl
has type
arbitrary = arbitrary
but is expected to have type
arbitrary = 0
-/
# end Ex
```
The theorem `defNatEq0` type checks because the type checker can unfold `(default : Nat)` and reduce it to `0`. This is not the case in the theorem `arbitraryNatEq0` because `arbitrary` is an opaque constant.
## Chaining Instances
@@ -194,7 +169,7 @@ This causes class inference to chain through instances recursively, backtracking
For example, the following definition shows that if two types ``a`` and ``b`` are inhabited, then so is their product:
```lean
instance [Inhabited a] [Inhabited b] : Inhabited (a × b) where
default := (arbitrary, arbitrary)
default := (default, default)
```
With this added to the earlier instance declarations, type class instance can infer, for example, a default element of ``Nat × Bool``:
```lean
@@ -205,19 +180,19 @@ With this added to the earlier instance declarations, type class instance can in
# default := true
# instance : Inhabited Nat where
# default := 0
# constant arbitrary [Inhabited a] : a :=
# opaque default [Inhabited a] : a :=
# Inhabited.default
instance [Inhabited a] [Inhabited b] : Inhabited (a × b) where
default := (arbitrary, arbitrary)
default := (default, default)
#eval (arbitrary : Nat × Bool)
#eval (default : Nat × Bool)
-- (0, true)
# end Ex
```
Similarly, we can inhabit type function with suitable constant functions:
```lean
instance [Inhabited b] : Inhabited (a -> b) where
default := fun _ => arbitrary
default := fun _ => default
```
As an exercise, try defining default instances for other types, such as `List` and `Sum` types.
@@ -229,7 +204,7 @@ and is useful for triggering the type class resolution procedure when the expect
def foo : Inhabited (Nat × Nat) :=
inferInstance
theorem ex : foo.default = (arbitrary, arbitrary) :=
theorem ex : foo.default = (default, default) :=
rfl
```
You can use the command `#print` to inspect how simple `inferInstance` is.

View File

@@ -32,10 +32,10 @@ Lean has numerous features, including:
- First-class functions
- Powerful data types
- Pattern matching
- [Type classes](typeclass.md)
- [Extensible syntax](syntax.md)
- [Type classes](./typeclass.md)
- [Extensible syntax](./syntax.md)
- Hygienic macros
- [Dependent types](deptypes.md)
- [Metaprogramming framework](metaprogramming.md)
- [Dependent types](https://leanprover.github.io/theorem_proving_in_lean4/dependent_type_theory.html)
- [Metaprogramming](./metaprogramming.md)
- Multithreading
- Verification: you can prove properties of your functions using Lean itself

101
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1638122382,
"narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=",
"lastModified": 1653893745,
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "74f7e4319258e287b0f9cb95426c9853b282730b",
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
"type": "github"
},
"original": {
@@ -30,6 +30,22 @@
"type": "github"
}
},
"lean4-mode": {
"flake": false,
"locked": {
"lastModified": 1654244721,
"narHash": "sha256-AVlr4+WGtJR9DGW/RBq+xNBlyrdmy6cg9dayKHGZowI=",
"owner": "leanprover",
"repo": "lean4-mode",
"rev": "c10def33f603a43f20a4d32d820b61f7ee5dbe5a",
"type": "github"
},
"original": {
"owner": "leanprover",
"repo": "lean4-mode",
"type": "github"
}
},
"lowdown-src": {
"flake": false,
"locked": {
@@ -46,33 +62,18 @@
"type": "github"
}
},
"mdBook": {
"flake": false,
"locked": {
"lastModified": 1637318029,
"narHash": "sha256-XU6oQY46mLqLdMp9ONR9WSEBVaA3627cGfzB218Wul0=",
"owner": "leanprover",
"repo": "mdBook",
"rev": "45de7509526f09915b19e4eaeec99c8c2031f1ce",
"type": "github"
},
"original": {
"owner": "leanprover",
"repo": "mdBook",
"type": "github"
}
},
"nix": {
"inputs": {
"lowdown-src": "lowdown-src",
"nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs",
"nixpkgs-regression": "nixpkgs-regression"
},
"locked": {
"lastModified": 1638447470,
"narHash": "sha256-DREkiGilBlNzBqonvVrIBNSsYWv1PZuvfXFhaSGeXsM=",
"lastModified": 1654239108,
"narHash": "sha256-0JzuElxLe5DxM+R4tvBYfvQnMGCERZy4KMRf0JYxxS4=",
"owner": "NixOS",
"repo": "nix",
"rev": "2ff71b021379a2c9bbdcb789a93cdc585b3520ca",
"rev": "1dd7253133c4dfd2e7a16ad6fe505442cef38a5b",
"type": "github"
},
"original": {
@@ -83,26 +84,43 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1632864508,
"narHash": "sha256-d127FIvGR41XbVRDPVvozUPQ/uRHbHwvfyKHwEt5xFM=",
"lastModified": 1645296114,
"narHash": "sha256-y53N7TyIkXsjMpOG7RhvqJFGDacLs9HlyHeSTBioqYU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "82891b5e2c2359d7e58d08849e4c89511ab94234",
"rev": "530a53dcbc9437363471167a5e4762c5fcfa34a1",
"type": "github"
},
"original": {
"id": "nixpkgs",
"owner": "NixOS",
"ref": "nixos-21.05-small",
"type": "indirect"
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-regression": {
"locked": {
"lastModified": 1643052045,
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1638397275,
"narHash": "sha256-2Jos1CJFTMO9IbulbM4PTKn24nISIDQCAG/AqYQ8rmg=",
"lastModified": 1654126564,
"narHash": "sha256-sgDXDKGmUG4h7OPDOHyQggFQ08ZqVzUIPi8351yhugY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "391f93a83c3a486475d60eb4a569bb6afbf306ad",
"rev": "f1c9c23aad972787f00f175651e4cb0d7c7fd5ea",
"type": "github"
},
"original": {
@@ -116,26 +134,9 @@
"inputs": {
"flake-utils": "flake-utils",
"lean-stage0": "lean-stage0",
"mdBook": "mdBook",
"lean4-mode": "lean4-mode",
"nix": "nix",
"nixpkgs": "nixpkgs_2",
"temci": "temci"
}
},
"temci": {
"flake": false,
"locked": {
"lastModified": 1638195132,
"narHash": "sha256-1DSg4Qr5h54wLrKpZfpkArhFXDFLdO57PiYUMk+7FSc=",
"owner": "parttimenerd",
"repo": "temci",
"rev": "a8d78cb52c248f1ae3f2469bbd0916b14ac9ea84",
"type": "github"
},
"original": {
"owner": "parttimenerd",
"repo": "temci",
"type": "github"
"nixpkgs": "nixpkgs_2"
}
}
},

View File

@@ -3,13 +3,9 @@
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixpkgs-unstable;
inputs.flake-utils.url = github:numtide/flake-utils;
inputs.temci = {
url = github:parttimenerd/temci;
flake = false;
};
inputs.nix.url = github:NixOS/nix;
inputs.mdBook = {
url = github:leanprover/mdBook;
inputs.lean4-mode = {
url = github:leanprover/lean4-mode;
flake = false;
};
# used *only* by `stage0-from-input` below
@@ -17,19 +13,18 @@
url = github:leanprover/lean4;
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
inputs.temci.follows = "temci";
inputs.nix.follows = "nix";
inputs.mdBook.follows = "mdBook";
inputs.lean4-mode.follows = "lean4-mode";
};
outputs = { self, nixpkgs, flake-utils, temci, nix, mdBook, lean-stage0 }: flake-utils.lib.eachDefaultSystem (system:
outputs = { self, nixpkgs, flake-utils, nix, lean4-mode, lean-stage0 }: flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
# for `vscode-with-extensions`
config.allowUnfree = true;
};
lean-packages = pkgs.callPackage (./nix/packages.nix) { inherit nix temci mdBook; };
lean-packages = pkgs.callPackage (./nix/packages.nix) { inherit nix lean4-mode; };
in {
packages = lean-packages // rec {
debug = lean-packages.override { debug = true; };
@@ -46,12 +41,21 @@
};
tsandebug = tsan.override { debug = true; };
stage0-from-input = lean-packages.override {
stage0 = lean-stage0.packages.${system}.lean;
stage0 = pkgs.writeShellScriptBin "lean" ''
exec ${lean-stage0.packages.${system}.lean}/bin/lean -Dinterpreter.prefer_native=false "$@"
'';
};
inherit self;
};
defaultPackage = lean-packages.lean-all;
devShell = pkgs.mkShell {
buildInputs = [ lean-packages.nix ];
shellHook = ''
export LEAN_SRC_PATH="$PWD/src"
'';
};
checks.lean = lean-packages.test;
}) // rec {
templates.pkg = {

View File

@@ -1,2 +0,0 @@
.cask
*.elc

View File

@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,79 +0,0 @@
Installation
============
To use `lean4-mode` in Emacs, add the following to your `init.el`:
```
;; You need to modify the following line
(setq load-path (cons "/path/to/lean4/lean4-mode" load-path))
(setq lean4-mode-required-packages '(dash f flycheck lsp-mode magit-section s))
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(package-initialize)
(let ((need-to-refresh t))
(dolist (p lean4-mode-required-packages)
(when (not (package-installed-p p))
(when need-to-refresh
(package-refresh-contents)
(setq need-to-refresh nil))
(package-install p))))
(require 'lean4-mode)
```
Alternatively if you are a fan of `use-package` and `straight.el` you
can use:
```
(use-package lean4-mode
:straight (lean4-mode :type git :host github :repo "leanprover/lean4"
:files ("lean4-mode/lean4*.el"))
;; to defer loading the package until required
:commands (lean4-mode))
```
If you are working on the `lean4` repository already and don't want to
have two separate checkouts you can use:
```
(use-package lean4-mode
:straight (lean4-mode :local-repo "/path/to/your/lean4"
:files ("lean4-mode/lean4*.el"))
;; to defer loading the package until required
:commands (lean4-mode))
```
Trying It Out
=============
If things are working correctly, you should see the word ``Lean 4`` in the
Emacs mode line when you open a file with extension `.lean`. Emacs will ask you
to identify the "project" this file belongs to. If you then type
```lean
#check id
```
the word ``#check`` will be underlined, and hovering over it will show
you the type of ``id``. The mode line will show ``FlyC:0/1``, indicating
that there are no errors and one piece of information displayed.
Settings
========
Set these with e.g. `M-x customize-variable`.
* `lsp-headerline-breadcrumb-enable`: show a "breadcrumb bar" of namespaces and sections surrounding the current location (default: off)
Key Bindings and Commands
=========================
| Key | Function |
|--------------------|---------------------------------------------------------------------------------|
| <kbd>C-c C-k</kbd> | show the keystroke needed to input the symbol under the cursor |
| <kbd>C-c C-d</kbd> | recompile & reload imports (`lean4-refresh-file-dependencies`) |
| <kbd>C-c C-x</kbd> | execute Lean in stand-alone mode (`lean4-std-exe`) |
| <kbd>C-c C-i</kbd> | toggle info view showing goals and errors at point (`lean4-toggle-info-buffer`) |
| <kbd>C-c ! n</kbd> | flycheck: go to next error |
| <kbd>C-c ! p</kbd> | flycheck: go to previous error |
For `lsp-mode` bindings, see https://emacs-lsp.github.io/lsp-mode/page/keybindings/ (not all capabilities are supported currently).
In the default configuration, the Flycheck annotation `FlyC:n/n` indicates the
number of errors / responses from Lean; clicking on `FlyC` opens the Flycheck menu.

View File

@@ -1,47 +0,0 @@
;; Copyright (c) 2014 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Soonho Kong
;;
(require 'cl-lib)
(defvar lean4-debug-mode nil)
(defvar lean4-debug-buffer-name "*lean4-debug*")
(defun lean4-turn-on-debug-mode (&optional print-msg)
(interactive)
(when (or (called-interactively-p 'any) print-msg)
(message "lean: turn on debug mode"))
(get-buffer-create lean4-debug-buffer-name)
(buffer-disable-undo lean4-debug-buffer-name)
(display-buffer lean4-debug-buffer-name 'display-buffer-reuse-window
'((reusable-frames . t)))
(setq lean4-debug-mode t))
(defun lean4-turn-off-debug-mode (&optional print-msg)
(interactive)
(when (eq major-mode 'lean4-mode)
(when (or (called-interactively-p 'any) print-msg)
(message "lean: turn off debug mode"))
(setq lean4-debug-mode nil)))
(defun lean4-output-to-buffer (buffer-name format-string args)
(with-current-buffer
(get-buffer-create buffer-name)
(save-selected-window
(ignore-errors
(select-window (get-buffer-window buffer-name t)))
(goto-char (point-max))
(insert (apply 'format format-string args)))))
(defun lean4-debug (format-string &rest args)
"Display a message at the bottom of the *lean4-debug* buffer."
(when lean4-debug-mode
(let ((time-str (format-time-string "%H:%M:%S.%3N" (current-time))))
(lean4-output-to-buffer lean4-debug-buffer-name
(concat "%s -- " format-string "\n")
(cons (propertize time-str 'face 'font-lock-keyword-face)
args)))))
(provide 'lean4-debug)

View File

@@ -1,19 +0,0 @@
;; -*- lexical-binding: t -*-
;;
;; Copyright (c) 2017 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Sebastian Ullrich
;;
(require 'f)
(require 'lean4-util)
(defun lean4-diff-test-file ()
"Use interactive ./test_input.sh on file of current buffer"
(interactive)
(save-buffer)
; yes: auto-agree to copying missing files
(message (shell-command-to-string (format "yes | PATH=%s/bin:$PATH ./test_single.sh -i \"%s\"" (lean4-get-rootdir) (f-filename (buffer-file-name))))))
(provide 'lean4-dev)

View File

@@ -1,208 +0,0 @@
;;; lean4-eri.el --- Enhanced relative indentation (eri)
;;; Commentary:
;; Adapted from agda-mode (https://github.com/agda/agda/blob/master/src/data/emacs-mode/eri.el)
;;; Code:
(require 'cl-lib)
(defun lean4-eri-current-line-length nil
"Calculate length of current line."
(- (line-end-position) (line-beginning-position)))
(defun lean4-eri-current-line-empty nil
"Return non-nil if the current line is empty (not counting white space)."
(equal (current-indentation)
(lean4-eri-current-line-length)))
(defun lean4-eri-maximum (xs)
"Calculate maximum element in XS.
Returns nil if the list is empty."
(if xs (apply 'max xs)))
(defun lean4-eri-take (n xs)
"Return the first N elements of XS."
(butlast xs (- (length xs) n)))
(defun lean4-eri-split (x xs)
"Return a pair of lists (XS1 . XS2).
If XS is sorted, then XS = (append XS1 XS2), and all elements in
XS1 are <= X, whereas all elements in XS2 are > X."
(let* ((pos (or (cl-position-if (lambda (y) (> y x)) xs) (length xs)))
(xs1 (lean4-eri-take pos xs))
(xs2 (nthcdr pos xs)))
(cons xs1 xs2)))
(defun lean4-eri-calculate-indentation-points-on-line (max)
"Calculate indentation points on current line.
Only points left of column number MAX are included. If MAX is
nil, then all points are included. Points are returned in
ascending order.
Example (positions marked with ^ are returned):
f x y = g 3 (Just y) 5 4
^ ^ ^ ^ ^ ^ ^ ^ |
|
MAX"
(let ((result))
(save-excursion
(save-restriction
(beginning-of-line)
; To make \\` work in the regexp below:
(narrow-to-region (line-beginning-position) (line-end-position))
(while
(progn
(let ((pos (and (search-forward-regexp
"\\(?:\\s-\\|\\`\\)\\(\\S-\\)" nil t)
(match-beginning 1))))
(when (not (null pos))
(let ((pos1 (- pos (line-beginning-position))))
(when (or (null max) (< pos1 max))
(add-to-list 'result pos1))))
(and pos
(< (point) (line-end-position))
(or (null max) (< (current-column) max))))))
(nreverse result) ; Destructive operation.
))))
(defun lean4-eri-new-indentation-points ()
"Calculate new indentation points.
Returns a singleton list containing the column number two steps
in from the indentation of the first non-empty line (white space
excluded) above the current line. If there is no such line,
then the empty list is returned."
(let ((start (line-beginning-position)))
(save-excursion
; Find a non-empty line above the current one, if any.
(while
(progn
(forward-line -1)
(not (or (bobp)
(not (lean4-eri-current-line-empty))))))
(if (or (equal (point) start)
(lean4-eri-current-line-empty))
nil
(list (+ 2 (current-indentation)))))))
(defun lean4-eri-calculate-indentation-points (reverse)
"Calculate points used to indent the current line.
The points are given in reverse order if REVERSE is non-nil. See
`lean4-eri-indent' for a description of how the indentation points are
calculated; note that the current indentation is not included in
the returned list."
;; First find a bunch of indentations used above the current line.
(let ((points)
(max)
(start (line-beginning-position)))
(save-excursion
(while
(progn
(forward-line -1)
; Skip the line we started from and lines with nothing but
; white space.
(unless (or (equal (point) start)
(lean4-eri-current-line-empty))
(setq points
(append
(lean4-eri-calculate-indentation-points-on-line max)
points))
(setq max (car points)))
;; Stop after hitting the beginning of the buffer or a
;; non-empty, non-indented line.
(not (or (bobp)
(and (equal (current-indentation) 0)
(> (lean4-eri-current-line-length) 0)))))))
;; Add new indentation points, but remove the current indentation.
;; Sort the indentations. Rearrange the points so that the next
;; point is the one after the current one. Reverse if necessary.
;;
;; Note: sort and nreverse are destructive.
(let* ((ps0 (remove (current-indentation)
(append (lean4-eri-new-indentation-points) points)))
(ps1 (lean4-eri-split (current-indentation) (sort ps0 '<)))
(ps2 (append (cdr ps1) (car ps1))))
(if reverse
(nreverse ps2)
ps2))))
(defun lean4-eri-indent (&optional reverse)
"Cycle between some possible indentation points.
With prefix argument REVERSE, cycle in reverse order.
Assume that a file contains the following lines of code, with
point on the line with three dots:
frob = loooooooooooooooooooooooooong identifier
foo = f a b
where
f (Foo x) y = let bar = x
baz = 3 + 5
...
^ ^ ^ ^ ^ ^ ^ ^ ^ * ^ ^ ^ ^
Then the ^'s and the * mark the indentation points that this
function cycles through. The indentation points are selected as
follows:
* All lines before the current one, up to and including the
first non-indented line (or the beginning of the buffer) are
considered.
foo = f a b
where
f (Foo x) y = let bar = x
baz = 3 + 5
* On these lines, erase all characters that stand to the right
of some non-white space character on a lower line.
foo
whe
f (Foo x) y = let b
baz = 3 + 5
* Also erase all characters not immediately preceded by white
space.
f
w
f ( x y = l b
b = 3 + 5
* The columns of all remaining characters are indentation
points.
f w f ( x y = l b = 3 + 5
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
* A new indentation point is also added, two steps in from the
indentation of the first non-empty line (white space
excluded) above the current line (if there is such a line).
f w f ( x y = l b = 3 + 5
^ ^ ^ ^ ^ ^ ^ ^ ^ * ^ ^ ^ ^"
(interactive "P")
(let* ((points (lean4-eri-calculate-indentation-points reverse))
(remaining-points (cdr (member (current-indentation) points)))
(indentation (if remaining-points
(car remaining-points)
(car points))))
(when indentation
(save-excursion (indent-line-to indentation))
(if (< (current-column) indentation)
(indent-line-to indentation)))))
(defun lean4-eri-indent-reverse nil
"Cycle between some possible indentation points (in reverse order).
See `lean4-eri-indent' for a description of how the indentation points
are calculated."
(interactive)
(lean4-eri-indent t))
(provide 'lean4-eri)
;;; lean4-eri.el ends here

Some files were not shown because too many files have changed in this diff Show More