Commit graph

158 commits

Author SHA1 Message Date
Leonardo de Moura
85c9ab072c feat: elaborate and delaborate decimals 2020-12-02 15:31:06 -08:00
Leonardo de Moura
facb28d080 feat: basic support for decimal numbers 2020-12-02 14:54:59 -08:00
Leonardo de Moura
c476954eef feat: heterogeneous OrElse and AndThen
@Kha I had a few issues similar to the `Append` issues.
We used a similar idiom for writing builtin parsers where we may write
```
def p : Parser := "foo " >> "bla "
```
as a shorthand for
```
def p : Parser := symbol "foo " >> symbol "bla "
```
I want to support `builtin syntax` one day :)

That being said, we should decide whether we keep `HAppend`, `HOrElse`,
and `HAndThen` or not.
The only one I wish I had in the past is `HAndThen`.
2020-12-01 18:32:24 -08:00
Leonardo de Moura
9d304df757 feat: heterogeneous Append experiment
@Kha This one required a bunch of manual fixes. The main issue is that
before we added the string interpolation feature, we created
`MessageData`s using `++` and coercions. For example, given
`(e : Expr)`, we would write
```
let msg : MessageData := "type: " ++ e
```
and rely on the coercions `String -> MessageData` and
`Expr -> MessageData`, and the instance `Append MessageData`.
However, heterogeneous operators "block" the expected type propagation downwards.
This kind of code is obsolete now since we can write a more compact
version using string interpolation
```
let msg := m!"type: {e}"
```
2020-12-01 16:32:41 -08:00
Leonardo de Moura
2120883307 refactor: heterogeneous operators
@Kha I had some unexpected surprises, but it is a good change.
Here is the summary.

1- We could get rid of `a %ₙ b` and `ModN` class. We can use `HMod`
instead. It was a positive surprise since I didn't remember we had
this `ModN` class.

2- Coercions are never used in heterogeneous operators. This is
expected since `a * b` is now notation for `HMul.hMul a b`, and
`a` and `b` may have different types. I manually added instances such
as `HMul Nat Int Int`. However, I did not try to add generic instances
such as
```
instance [Coe a b] [Mul b] : HMul a b b where
  hMul x y := mul (coe x) y
```
I will try later.

3- Give `h : cs.size > 0`, I got a type error at
```
let idx : Fin cs.size := ⟨cs.size - 1, Nat.predLt h⟩
```
`Nat.predLt h` has type `Nat.pred cs.size < cs.size`
However, `Nat.pred cs.size` doesn't unify with `cs.size - 1`.
The problem is that we can't synthesize the `HSub` instance until
we apply the default instances.
It worked before because `isDefEq` would force the pending TC
problem `Sub Nat` to be resolved, and after that we would be able
to reduce `cs.size - 1` and establish that it is definitionally
equal to `Nat.pred cs.size`.
I considered two possible workarounds
a) `let idx : Fin cs.size := ⟨cs.size - (1:Nat), Nat.predLt h⟩`
b) `let idx : Fin cs.size := ⟨cs.size - 1, by exact Nat.predLt h⟩`
The first one works because we are not providing enough information
for synthesizing the `HSub` instance. The second works because it
postpones the elaboration of `Nat.predLt h`. The default instances
will be applied before we start applying tactics.

4- The `.` notation is affected too. For example, `(x + 1).toUInt8`
doesn't work since we don't know the type of `x+1` until we apply
default instances. I fixed it by using `(x + (1:Nat)).toUInt8`.
Another possible fix is `Nat.toUInt8 (x + 1)`.
Similarly, `(x+1).fold ...` doesn't work.

5- The following code failed to be elaborated
```
indent (push s!"{ss'}\n") (some (0 - Format.getIndent (← getOptions)))
```
It was working before, but it relied on how the expected type is
propagated. The elaborator process
```
some (0 - Format.getIndent (← getOptions))
```
with expected type `(Option Int)`. So, the `-` is interpreted as
`Int.sub` although `Format.getIndent (← getOptions)` has type `Nat`.
In the new `HSub`, the expected type doesn't really influence TC
resolution since it is an `outparam`. So, we failed with the error
failed to synthesize `HSub Nat Nat Int`.
One possible fix was to add the instance `HSub Nat Nat Int` with
`Int.sub`, but I used the following fix
```
some ((0 : Int) - Format.getIndent (← getOptions))
```
which makes it clear that we want the `Int.sub` operator instead of
`Nat.sub`.
2020-12-01 14:02:46 -08:00
Sebastian Ullrich
07f25a19db chore: remove obsolete builtin delaborators 2020-12-01 11:57:20 -08:00
Sebastian Ullrich
d18596d4ca feat: add Unexpander for delaborating without importing Lean, use for simple notations
/cc @leodemoura
2020-12-01 11:57:20 -08:00
Leonardo de Moura
27292c4f60 chore: prepare to change OfNat type class 2020-12-01 06:59:16 -08:00
Sebastian Ullrich
6d9fcd1d07 fix: renamed references 2020-11-30 14:41:10 +01:00
Sebastian Ullrich
f6816a0ffa refactor: move & split Lean.Delaborator 2020-11-30 13:52:46 +01:00
Sebastian Ullrich
1bcc8f7c16 chore: parenthesizer: more helpful panic message 2020-11-28 12:37:35 +01:00
Leonardo de Moura
0869f38de4 chore: update structure, class, inductive 2020-11-27 15:09:30 -08:00
Leonardo de Moura
d6f778bec4 refactor: arbitrary without explicit arguments
@Kha I was tired of writing `arbitrary _` :)
There 0 places in the stdlib where the type needs to be provided.
If in the future we need to specify the type we can use
`arbitrary (α := <type>)`
2020-11-25 09:07:38 -08:00
Sebastian Ullrich
cf9a2ae6af feat: formatter: preserve comments 2020-11-25 11:30:24 +01:00
Sebastian Ullrich
33c1e5ed9e fix: formatter: ignore all but one choice node 2020-11-25 11:30:24 +01:00
Sebastian Ullrich
6126fd6388 chore: improve pretty printer traces, avoid recursion 2020-11-25 11:30:24 +01:00
Leonardo de Moura
91dca53274 refactor: remove MonadIO
There is no reason for having `MonadIO` anymore. The `MonadLift` type
class is well behaved in the new frontend, the `MonadFinally` solves
the problem at monad stacks such as `ExcepT e IO`.

This commit also changes the type of the IO printing functions.
For example, the type of `IO.println` was
```
def IO.println {m} [MonadIO m] {α} [ToString α] (s : α) : m Unit
```
and now it is just
```
def IO.println {α} [ToString α] (s : α) : IO Unit
```
We rely on the new frontend auto-lifting feature.
That is, if there is an instance `[MonadLiftT IO m]`, then
a term of type `IO a` is automatically coerced to `m a`

We also want a simpler `IO.println` for writing tests.
For example,
```
```
doesn't work because there isn't sufficient information for inferring
the parameter `m` in the previous `IO.println`.
The shortest workaround looked very weird
```
```

I considered adding `IO` as a default value for `m` when we have
`MonadIO m`, as we use `Nat` as the default for `ofNat a`, but it felt
like uncessary complexity.

@Kha The commit seems to work well. The auto-lifting featuring has
been working great for me. There is still room for improvement.
For example, given `MonadLiftT m n`, it doesn't automatically lift
`a -> m b` into `a -> n b`. So, code such as
`foo >>= IO.println`
had to be rewritten as
`foo >>= fun x => IO.println x`
I will add this feature later.
If you have time, please try to play with this feature and figure out
if it is stable enough for making it the default.
That is, if it roboust enough, we can stop using the following idiom
for writing functions that can be lifted automatically.
```
def instantiateLevelMVarsImp (u : Level) : MetaM Level :=
  ...

def instantiateLevelMVars {m} [MonadLiftT MetaM m] (u : Level) : m Level :=
  liftMetaM $ instantiateLevelMVarsImp u
```
I think we only need this idiom when using `MonadControlT` which is
not as common as `MonadLiftT`.
2020-11-18 18:47:22 -08:00
Leonardo de Moura
360fa1638f chore: rename Parser.try to Parser.atomic
Reason: `try` is a keyword.

cc @Kha
2020-11-17 08:25:01 -08:00
Leonardo de Moura
db5fe843de chore: add expandInterpolatedStr helper function, rename msg! => m! 2020-11-14 13:52:52 -08:00
Leonardo de Moura
bed1582844 chore: remove workaround of the workaround 2020-11-14 07:04:17 -08:00
Leonardo de Moura
35f1844d16 feat: add ParserDescr.checkPrec 2020-11-13 16:00:31 -08:00
Leonardo de Moura
f64d6c4514 feat: add ParserDescr.nodeWithAntiquot 2020-11-13 16:00:31 -08:00
Leonardo de Moura
0510f746fc feat: add macro registerParserAlias!
It register the parser, parenthesizer, and formatter.
2020-11-11 19:34:14 -08:00
Leonardo de Moura
3bfc5248ca chore: ParserDescrNew => ParserDescr 2020-11-11 18:57:49 -08:00
Leonardo de Moura
ba9a06dfc9 feat: compact ParserDescr 2020-11-11 18:52:26 -08:00
Leonardo de Moura
bd8bb163e2 feat: add parser aliases tables 2020-11-11 17:41:20 -08:00
Leonardo de Moura
f17e226638 chore: naming convention
Example: `mkNameStr` => `Name.mkStr`

cc @Kha
2020-11-11 10:08:55 -08:00
Leonardo de Moura
fc4d991707 feat: add allowTrailingSep parameter to ParserDescr.sepBy and ParserDescr.sepBy1 2020-11-08 07:51:10 -08:00
Leonardo de Moura
34cba1ec2e feat: add withPosition and checkCol constructors 2020-11-08 06:42:25 -08:00
Leonardo de Moura
81d6e065e7 chore: adjust files and tests 2020-11-07 17:32:12 -08:00
Sebastian Ullrich
c1d75e21ea fix: fix pretty printers for imported ParserDescrs
... by interpreting them (imported or not) on the fly instead of storing them in the environment

/cc @leodemoura
2020-11-07 17:05:07 +01:00
Leonardo de Moura
0a56057db1 feat: better error message for "unknown" tactic
@Kha The hack I posted at Zulip didn't really work
```
macro x:ident : tactic => throw $ Lean.Macro.Exception.error x s!"unknown tactic '{x.getId}'"
```

For example, we would still get a weird error message at
```
theorem ex3 (x : Nat) : x = x → x = x :=
  have x = x by foo (aaa bbb) -- The error would be at `bbb`
  fun h => h
```
There were other minor issues that could be fixed, but this one was bad.
2020-10-30 14:58:17 -07:00
Leonardo de Moura
6858cb5fb6 chore: cleanup 2020-10-29 10:24:16 -07:00
Leonardo de Moura
13a3215d0d chore: use Subarray combinators 2020-10-28 19:52:59 -07:00
Leonardo de Moura
4ba21ea10c chore: cleanup src/Array/Basic.lean 2020-10-28 19:35:42 -07:00
Leonardo de Moura
898a08a0c1 chore: avoid Has prefix in type classes
closes #203
2020-10-27 18:29:19 -07:00
Leonardo de Moura
633578cfaf chore: use StateRefT macro 2020-10-27 13:05:12 -07:00
Sebastian Ullrich
d8a1742d57 feat: introduce suppressInsideQuot 2020-10-27 16:50:58 +01:00
Sebastian Ullrich
20ed65605b fix: don't parenthesize juxtaposed tactics 2020-10-27 14:09:33 +01:00
Sebastian Ullrich
84692acd0e fix: do not introduce parentheses implied by indentation 2020-10-27 14:09:33 +01:00
Sebastian Ullrich
5f67c359bc chore: simplify formatter token separation logic 2020-10-27 14:09:33 +01:00
Sebastian Ullrich
33c861a80e fix: parenthesizer: really make sure a trailing parser is of the same category as the continuation 2020-10-27 14:09:33 +01:00
Sebastian Ullrich
eb125c52f1 fix: never pretty-print whitespace before checkNoWsBefore 2020-10-27 14:09:33 +01:00
Leonardo de Moura
7e244686e9 chore: remove old notation 2020-10-26 09:16:51 -07:00
Leonardo de Moura
13c2a8ff51 chore: remove #lang lean4 header 2020-10-25 09:54:07 -07:00
Leonardo de Moura
af968c60e6 chore: cleanup 2020-10-22 07:32:23 -07:00
Sebastian Ullrich
7f8d6b803f feat: interpolatedStr pretty printer 2020-10-22 15:01:53 +02:00
Leonardo de Moura
b555307f06 chore: move to new frontend 2020-10-21 16:35:50 -07:00
Leonardo de Moura
8abbf7634d chore: move to new frontend 2020-10-21 14:16:41 -07:00
Leonardo de Moura
7111eb4d79 chore: move to new frontend 2020-10-21 13:30:43 -07:00