Commit graph

11 commits

Author SHA1 Message Date
Kyle Miller
925a6befd4
fix: do not pretty print theorems with generalized field notation (#3750)
For example, pretty print as `Nat.add_comm m n` rather than as
`m.add_comm n`.
2024-03-23 09:20:48 +00:00
Kyle Miller
d39b0415f0
feat: enable pp.fieldNotation.generalized globally (#3744)
Sets the default value to `pp.fieldNotation.generalized` to `true`.
Updates tests, and fixes some minor flaws in the implementation of the
generalized field notation pretty printer.

Now generalized field notation won't be used for any function that has a
`motive` argument. This is intended to prevent recursors from pretty
printing using it as (1) recursors are more like control flow structures
than actual functions and (2) generalized field notation tends to cause
elaboration problems for recursors.

Note: be sure functions that have an `@[app_unexpander]` use
`@[pp_nodot]` if applicable. For example, `List.toArray` needs
`@[pp_nodot]` to ensure the unexpander prints it using `#[...]`
notation.
2024-03-23 02:38:09 +00:00
Leonardo de Moura
a6cdc333d5 chore: fix tests 2024-02-18 14:14:55 -08:00
Joachim Breitner
de23226d0c
refactor: fuse nested mkCongrArg calls (#3203)
Encouraged by the performance gains from making `rewrite` produce
smaller proof objects
(#3121) I am here looking for low-hanging fruit in `simp`.

Consider this typical example:

```
set_option pp.explicit true

theorem test
  (a : Nat)
  (b : Nat)
  (c : Nat)
  (heq : a = b)
  (h : (c.add (c.add ((c.add b).add c))).add c = c)
  : (c.add (c.add ((c.add a).add c))).add c = c
```
We get a rather nice proof term when using
```
  := by rw [heq]; assumption
```
namely
```
theorem test : ∀ (a b c : Nat),
  @Eq Nat a b →
    @Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) c) c →
      @Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))) c) c :=
fun a b c heq h =>
  @Eq.mpr (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))) c) c)
    (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) c) c)
    (@congrArg Nat Prop a b (fun _a => @Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c _a) c))) c) c) heq) h
```
(this is with #3121).

But with `by simp only [heq]; assumption`, it looks rather different:

```
theorem test : ∀ (a b c : Nat),
  @Eq Nat a b →
    @Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) c) c →
      @Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))) c) c :=
fun a b c heq h =>
  @Eq.mpr (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))) c) c)
    (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) c) c)
    (@id
      (@Eq Prop (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))) c) c)
        (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) c) c))
      (@congrFun Nat (fun a => Prop) (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))) c))
        (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) c))
        (@congrArg Nat (Nat → Prop) (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))) c)
          (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) c) (@Eq Nat)
          (@congrFun Nat (fun a => Nat) (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))))
            (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))))
            (@congrArg Nat (Nat → Nat) (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c)))
              (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) Nat.add
              (@congrArg Nat Nat (Nat.add c (Nat.add (Nat.add c a) c)) (Nat.add c (Nat.add (Nat.add c b) c)) (Nat.add c)
                (@congrArg Nat Nat (Nat.add (Nat.add c a) c) (Nat.add (Nat.add c b) c) (Nat.add c)
                  (@congrFun Nat (fun a => Nat) (Nat.add (Nat.add c a)) (Nat.add (Nat.add c b))
                    (@congrArg Nat (Nat → Nat) (Nat.add c a) (Nat.add c b) Nat.add
                      (@congrArg Nat Nat a b (Nat.add c) heq))
                    c))))
            c))
        c))
    h
```
Since simp uses only single-step `congrArg`/`congrFun` congruence lemmas
here, the proof
term grows very large, likely quadratic in this case.

Can we do better? Every nesting of `congrArg` (and it's little brother
`congrFun`) can be
turned into a single `congrArg` call. 

In this PR I make making the smart app builders `Meta.mkCongrArg` and
`Meta.mkCongrFun` a bit
smarter and not only fuse with `Eq.refl`, but also with
`congrArg`/`congrFun`.

Now we get, in this simple example,
```
theorem test : ∀ (a b c : Nat),
  @Eq Nat a b →
    @Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) c) c →
      @Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))) c) c :=
fun a b c heq h =>
  @Eq.mpr (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c a) c))) c) c)
    (@Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c b) c))) c) c)
    (@congrArg Nat Prop a b (fun x => @Eq Nat (Nat.add (Nat.add c (Nat.add c (Nat.add (Nat.add c x) c))) c) c) heq) h
```

Let’s see if it works and how much we gain.
2024-01-25 17:48:27 +00:00
Leonardo de Moura
25baf73005 feat: replace ite and dite shortcircuit theorems with simproc
Motivation: better `simp` cache behavior. Recall that `simp` cache
uses `dischargeDepth`.
2024-01-09 12:57:15 +01:00
Leonardo de Moura
22c8154811 feat: add pre simp lemmas for if-then-else terms
See new test for example that takes exponential time without new simp
theorems.
TODO: replace auxiliary theorems with simprocs as soon as we implement them.
2024-01-09 12:57:15 +01:00
Leonardo de Moura
041827bed5 chore: unused variables 2022-06-07 17:54:10 -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
ff76958959 feat: basic support for linear Nat arithmetic at simp 2022-02-26 08:58:32 -08:00
Gabriel Ebner
b905824024 chore: fix tests 2021-12-15 11:42:38 +00:00
Leonardo de Moura
e667385cf5 feat: simpLet when zeta reduction is disabled 2021-09-10 19:34:38 -07:00