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.
This commit is contained in:
Kyle Miller 2024-03-22 19:38:09 -07:00 committed by GitHub
parent 8ce98e62ac
commit d39b0415f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
72 changed files with 293 additions and 303 deletions

View file

@ -57,9 +57,9 @@ v4.8.0 (development in progress)
rather than `{a := x, b := y, c := z}`.
This attribute is applied to `Sigma`, `PSigma`, `PProd`, `Subtype`, `And`, and `Fin`.
* Option `pp.structureProjections` is renamed to `pp.fieldNotation`, and there is a new suboption `pp.fieldNotation.generalized`
to enable pretty printing function applications using generalized field notation.
Field notation can now be disabled function-by-function using the `@[pp_nodot]` attribute.
* Option `pp.structureProjections` is renamed to `pp.fieldNotation`, and there is now a suboption `pp.fieldNotation.generalized`
to enable pretty printing function applications using generalized field notation (defaults to true).
Field notation can be disabled on a function-by-function basis using the `@[pp_nodot]` attribute.
Breaking changes:

View file

@ -2755,7 +2755,7 @@ def List.redLength : List α → Nat
/-- Convert a `List α` into an `Array α`. This is O(n) in the length of the list. -/
-- This function is exported to C, where it is called by `Array.mk`
-- (the constructor) to implement this functionality.
@[inline, match_pattern, export lean_list_to_array]
@[inline, match_pattern, pp_nodot, export lean_list_to_array]
def List.toArray (as : List α) : Array α :=
as.toArrayAux (Array.mkEmpty as.redLength)

View file

@ -17,12 +17,12 @@ namespace Lean.PrettyPrinter.Delaborator
open Meta
/--
If this is a structure projection that could delaborate using dot notation,
If this constant is a structure projection that could delaborate using dot notation,
returns the field name, the number of parameters before the structure argument, and whether this is a parent projection.
Otherwise it fails.
-/
private def projInfo (f : Expr) : MetaM (Name × Nat × Bool) := do
let .const c@(.str _ field) _ := f.consumeMData | failure
private def projInfo (c : Name) : MetaM (Name × Nat × Bool) := do
let .str _ field := c | failure
let field := Name.mkSimple field
let env ← getEnv
let some info := env.getProjectionFnInfo? c | failure
@ -33,32 +33,46 @@ private def projInfo (f : Expr) : MetaM (Name × Nat × Bool) := do
return (field, info.numParams, isParentProj)
/--
If this function application could delaborate using generalized field notation,
Like `Lean.Elab.Term.typeMatchesBaseName` but does not use `Function` for pi types.
-/
private def typeMatchesBaseName (type : Expr) (baseName : Name) : MetaM Bool := do
if type.cleanupAnnotations.isAppOf baseName then
return true
else
return (← whnfR type).isAppOf baseName
/--
If this constant application could delaborate using generalized field notation with little confusion,
returns the field name and the index for the argument to be used as the object of the field notation.
Otherwise it fails.
-/
private def generalizedFieldInfo (f : Expr) (args : Array Expr) : MetaM (Name × Nat) := do
let .const name@(.str _ field) .. := f.consumeMData | failure
private def generalizedFieldInfo (c : Name) (args : Array Expr) : MetaM (Name × Nat) := do
let .str _ field := c | failure
let field := Name.mkSimple field
let baseName := name.getPrefix
let baseName := c.getPrefix
guard <| !baseName.isAnonymous
Meta.forallBoundedTelescope (← instantiateMVars <| ← inferType f) args.size fun params _ => do
-- Disallow `Function` since it is used for pi types.
guard <| baseName != `Function
let info ← getConstInfo c
-- Search for the first argument that could be used for field notation
-- and make sure it is the first explicit argument.
Meta.forallBoundedTelescope info.type args.size fun params _ => do
for i in [0:params.size] do
let fvarId := params[i]!.fvarId!
if (← fvarId.getBinderInfo).isExplicit then
-- We only consider the first explicit argument, so fail if the parameter does not have the correct type.
guard <| (← fvarId.getType).cleanupAnnotations.isAppOf baseName
let argTy ← instantiateMVars <| ← inferType args[i]!
-- Generalized field notation allows either an an exact match, or a match after `whnfR`.
if argTy.consumeMData.isAppOf baseName then
return (field, i)
else if (← Meta.whnfR argTy).isAppOf baseName then
return (field, i)
else
failure
-- If there is a motive, we will treat this as a sort of control flow structure and so we won't use field notation.
-- Plus, recursors tend to be riskier when using dot notation.
if (← fvarId.getUserName) == `motive then
failure
if (← typeMatchesBaseName (← fvarId.getType) baseName) then
guard (← fvarId.getBinderInfo).isExplicit
-- We require an exact match for the base name.
-- While `Lean.Elab.Term.resolveLValLoop` is able to unfold the type and iterate, we do not attempt to exploit this feature.
-- (To get it right, we would need to check that each relevant namespace does not contain a declaration named `field`.)
guard <| (← instantiateMVars <| ← inferType args[i]!).consumeMData.isAppOf baseName
return (field, i)
else
-- If not explicit, then make sure that this parameter can't be used for field notation.
guard <| ! (← fvarId.getType).cleanupAnnotations.isAppOf baseName
-- We only use the first explicit argument for field notation.
guard !(← fvarId.getBinderInfo).isExplicit
failure
/--
@ -67,20 +81,20 @@ returns the field name to use and the argument index for the object of the field
-/
def fieldNotationCandidate? (f : Expr) (args : Array Expr) (useGeneralizedFieldNotation : Bool) : MetaM (Option (Name × Nat)) := do
let env ← getEnv
let .const name .. := f.consumeMData | return none
if name.getPrefix.isAnonymous then return none
let .const c .. := f.consumeMData | return none
if c.getPrefix.isAnonymous then return none
-- If there is `pp_nodot` on this function, then don't use field notation for it.
if hasPPNoDotAttribute env name then
if hasPPNoDotAttribute env c then
return none
-- Handle structure projections
try
let (field, numParams, _) ← projInfo f
let (field, numParams, _) ← projInfo c
return (field, numParams)
catch _ => pure ()
-- Handle generalized field notation
if useGeneralizedFieldNotation then
try
return ← generalizedFieldInfo f args
return ← generalizedFieldInfo c args
catch _ => pure ()
-- It's not handled by any of the above.
return none
@ -92,7 +106,8 @@ If `explicit` is `true`, then further requires that the structure have no parame
def isParentProj (explicit : Bool) (e : Expr) : MetaM Bool := do
unless e.isApp do return false
try
let (_, numParams, isParentProj) ← projInfo e.getAppFn
let .const c .. := e.getAppFn | failure
let (_, numParams, isParentProj) ← projInfo c
return isParentProj && (!explicit || numParams == 0) && e.getAppNumArgs == numParams + 1
catch _ =>
return false

View file

@ -96,7 +96,7 @@ register_builtin_option pp.fieldNotation : Bool := {
descr := "(pretty printer) use field notation when pretty printing, including for structure projections, unless '@[pp_nodot]' is applied"
}
register_builtin_option pp.fieldNotation.generalized : Bool := {
defValue := false -- TODO(kmill): set to true
defValue := true
group := "pp"
descr := "(pretty printer) when `pp.fieldNotation` is true, enable using generalized field notation when the argument for field notation is the first explicit argument"
}

View file

@ -1,3 +1,3 @@
n : Nat
f : Fin (Nat.succ n)
f : Fin n.succ
⊢ foo f = 0

View file

@ -3,6 +3,6 @@ fun {α β γ} x x_1 =>
match β, γ, x, x_1 with
| β, .(β), Arrow.id, g => g
| .(α), γ, f, Arrow.id => f
| β, γ, Arrow.comp f₁ f₂, g => Arrow.comp f₁ (Arrow.comp f₂ g)
| β, γ, f, g => Arrow.comp f g
| β, γ, f₁.comp f₂, g => f₁.comp (f₂.comp g)
| β, γ, f, g => f.comp g
Arrow.unit

View file

@ -1,5 +1,5 @@
1616.lean:10:24-10:41: error: don't know how to synthesize implicit argument
@Linear ?m ?m (?m :: ?m) (?m :: ?m) (Cover.right c)
@Linear ?m ?m (?m :: ?m) (?m :: ?m) c.right
context:
c : Cover ?m ?m ?m
⊢ Type u_1
@ -14,12 +14,12 @@ context:
c : Cover ?m ?m ?m
⊢ Type u_1
1616.lean:9:23-9:39: error: don't know how to synthesize implicit argument
@Linear ?m (?m :: ?m) ?m (?m :: ?m) (Cover.left c)
@Linear ?m (?m :: ?m) ?m (?m :: ?m) c.left
context:
c : Cover ?m ?m ?m
⊢ List ?m
1616.lean:10:24-10:41: error: don't know how to synthesize implicit argument
@Linear ?m ?m (?m :: ?m) (?m :: ?m) (Cover.right c)
@Linear ?m ?m (?m :: ?m) (?m :: ?m) c.right
context:
c : Cover ?m ?m ?m
⊢ List ?m
@ -34,17 +34,17 @@ context:
c : Cover ?m ?m ?m
⊢ Type u_1
1616.lean:9:23-9:39: error: don't know how to synthesize implicit argument
@Linear ?m (?m :: ?m) ?m (?m :: ?m) (Cover.left c)
@Linear ?m (?m :: ?m) ?m (?m :: ?m) c.left
context:
c : Cover ?m ?m ?m
⊢ Type u_1
1616.lean:10:24-10:41: error: don't know how to synthesize implicit argument
@Linear ?m ?m (?m :: ?m) (?m :: ?m) (Cover.right c)
@Linear ?m ?m (?m :: ?m) (?m :: ?m) c.right
context:
c : Cover ?m ?m ?m
⊢ List ?m
1616.lean:9:23-9:39: error: don't know how to synthesize implicit argument
@Linear ?m (?m :: ?m) ?m (?m :: ?m) (Cover.left c)
@Linear ?m (?m :: ?m) ?m (?m :: ?m) c.left
context:
c : Cover ?m ?m ?m
⊢ List ?m

View file

@ -1,4 +1,4 @@
theorem ex1 : ∀ {p q : Prop}, (p ↔ q) → P q → P p :=
fun {p q} h h' => Eq.mpr (id (propext (P_congr p q h))) h'
fun {p q} h h' => (id (propext (P_congr p q h))).mpr h'
theorem ex2 : ∀ {p q : Prop}, p = q → P q → P p :=
fun {p q} h h' => Eq.mpr (id (propext (P_congr p q (Iff.of_eq h)))) h'
fun {p q} h h' => (id (propext (P_congr p q (Iff.of_eq h)))).mpr h'

View file

@ -1,12 +1,12 @@
2161.lean:15:48-15:54: error: tactic 'decide' failed for proposition
mul (mul (mul 4 1) 1) 1 = 4
((mul 4 1).mul 1).mul 1 = 4
since its 'Decidable' instance reduced to
Decidable.rec (fun h => (fun h => isFalse ⋯) h) (fun h => (fun h => h ▸ isTrue ⋯) h)
(instDecidableEqNat (mul (mul (mul 4 1) 1) 1).num 4)
(instDecidableEqNat (((mul 4 1).mul 1).mul 1).num 4)
rather than to the 'isTrue' constructor.
2161.lean:22:48-22:54: error: tactic 'decide' failed for proposition
add (add (add 4 1) 1) 1 = 4
((add 4 1).add 1).add 1 = 4
since its 'Decidable' instance reduced to
Decidable.rec (fun h => (fun h => isFalse ⋯) h) (fun h => (fun h => h ▸ isTrue ⋯) h)
(instDecidableEqNat (add (add (add 4 1) 1) 1).num 4)
(instDecidableEqNat (((add 4 1).add 1).add 1).num 4)
rather than to the 'isTrue' constructor.

View file

@ -1,4 +1,4 @@
Set.insert (Set.insert (Set.insert Set.empty 1) 2) 3 : Set Nat
((Set.empty.insert 1).insert 2).insert 3 : Set Nat
fun x y => g { x := x, y := y } : Nat → Nat → Nat
fun x y => Set.insert (Set.insert Set.empty x) y : Nat → Nat → Set Nat
fun x y => (Set.empty.insert x).insert y : Nat → Nat → Set Nat
fun x y => { x := x, y := y } : Nat → Nat → Point

View file

@ -1,7 +1,7 @@
true
(match i with
| 0 => true
| Nat.succ n => true) &&
| n.succ => true) &&
f i
if i < 5 then 0 else 1
if i < 5 then 0 else g i j

View file

@ -2,7 +2,7 @@
context:
m n : Nat
ih : m * n = n * m
⊢ m * n + m = m * n + succ zero * m
⊢ m * n + m = m * n + zero.succ * m
449.lean:13:19-13:20: error: don't know how to synthesize placeholder
context:
x y : Prop

View file

@ -1,8 +1,8 @@
let y := Nat.zero;
Nat.add y y
fun y_1 => Nat.add y y_1
y.add y
fun y_1 => y.add y_1
fun y => Nat.add _fvar.1 y
fun (y : Nat) => Nat.add y y
Nat.add ?m y
?m.add y
Nat.add (?m #0) #0
fun y => Nat.add (Nat.add y y) y
fun y => (y.add y).add y

View file

@ -1,4 +1,4 @@
550.lean:3:2-3:6: error: unsolved goals
x : Nat
h : ∀ (x : Nat), x + 1 = Nat.succ x
Nat.succ (x + 1) = 1 + (x + 1)
h : ∀ (x : Nat), x + 1 = x.succ
⊢ (x + 1).succ = 1 + (x + 1)

View file

@ -2,12 +2,12 @@
690.lean:6:0-6:7: warning: declaration uses 'sorry'
case step
a b m✝ : Nat
hStep : Nat.le a m✝
ih : Nat.le a (m✝ + 1)
Nat.le a (Nat.succ m✝ + 1)
hStep : a.le m✝
ih : a.le (m✝ + 1)
a.le (m✝.succ + 1)
690.lean:11:0-11:7: warning: declaration uses 'sorry'
case step
a b x : Nat
hStep : Nat.le a x
ih : Nat.le a (x + 1)
Nat.le a (Nat.succ x + 1)
hStep : a.le x
ih : a.le (x + 1)
a.le (x.succ + 1)

View file

@ -1,14 +1,14 @@
i j : Nat
a : Array Nat
v : Nat
h₁ : i < Array.size a
h₂ : j < Array.size a
h₁ : i < a.size
h₂ : j < a.size
h₃ : i = j
⊢ f a i v h₁ = f a j v h₂
i j : Nat
a : Array Nat
v : Nat
h₁ : 0 + i < Array.size a
h₂ : j < Array.size a
h₁ : 0 + i < a.size
h₂ : j < a.size
h₃ : i = j
⊢ f a i v (Nat.zero_add i ▸ h₁) = f a j v h₂
⊢ f a i v (i.zero_add ▸ h₁) = f a j v h₂

View file

@ -2,5 +2,5 @@ autoImplicitChainNameIssue.lean:8:11-8:15: error: unsolved goals
case nil
α✝ : Type u_1
as : List α✝
⊢ Palindrome (List.reverse [])
palindrome_reverse.{u_1} : ∀ {α : Type u_1} {as : List α}, Palindrome as → Palindrome (List.reverse as)
⊢ Palindrome [].reverse
palindrome_reverse.{u_1} : ∀ {α : Type u_1} {as : List α}, Palindrome as → Palindrome as.reverse

View file

@ -5,4 +5,4 @@ case z
case s
a✝ : Nat
a_ih✝ : add Nat.z a✝ = a✝
⊢ add Nat.z (Nat.s a✝) = Nat.s a✝
⊢ add Nat.z a✝.s = a✝.s

View file

@ -4,7 +4,7 @@ cap : Nat
backing : Fin cap → Option α
size : Nat
h_size : size ≤ cap
h_full : ∀ (i : Nat) (h : i < size), Option.isSome (backing ⟨i, ⋯⟩) = true
h_full : ∀ (i : Nat) (h : i < size), (backing ⟨i, ⋯⟩).isSome = true
i : Nat
h : i < size
Option.isSome (if h_1 : i < cap then backing ⟨i, ⋯⟩ else none) = true
⊢ (if h_1 : i < cap then backing ⟨i, ⋯⟩ else none).isSome = true

View file

@ -5,10 +5,10 @@ x y : Nat
x y : Nat
| x + y = y + x + 0
x y : Nat
⊢ x + y = Nat.add y x
⊢ x + y = y.add x
case x
x y : Nat
⊢ x + y = Nat.add y x
⊢ x + y = y.add x
case a
a b : Nat
| foo (0 + a) (b + 0)
@ -48,11 +48,11 @@ case y
a b : Nat
| b
x y : Nat
⊢ x + y = Nat.add y x
⊢ x + y = y.add x
x y : Nat
Nat.add x y = Nat.add y x
x.add y = y.add x
x y : Nat
⊢ f x (Nat.add x y) y = y + x
⊢ f x (x.add y) y = y + x
x y : Nat
| x + y
case h.h

View file

@ -1,2 +1,2 @@
constructor Ring.mk.{u} : {R : Type u} → [toZero : Zero R] → (gsmul : Int → R → R) → (∀ (a : R), gsmul 0 a = 0) → Ring R
Ring.mk (fun x n => Int.toNat x * n) ⋯ : Ring Nat
Ring.mk (fun x n => x.toNat * n) ⋯ : Ring Nat

View file

@ -5,15 +5,15 @@ has type
but is expected to have type
IO PUnit : Type
doIssue.lean:10:2-10:13: error: type mismatch
Array.set! xs 0 1
xs.set! 0 1
has type
Array Nat : Type
but is expected to have type
IO PUnit : Type
doIssue.lean:18:7-18:20: error: application type mismatch
pure (Array.set! xs 0 1)
pure (xs.set! 0 1)
argument
Array.set! xs 0 1
xs.set! 0 1
has type
Array Nat : Type
but is expected to have type

View file

@ -1,5 +1,5 @@
[Meta.debug] >> fun x => Nat.add
[Meta.debug] >> Nat.add
[Meta.debug] >> HAdd.hAdd 1
[Meta.debug] >> fun x y z => Nat.add z y
[Meta.debug] >> fun y => Nat.add y y
[Meta.debug] >> fun x y z => z.add y
[Meta.debug] >> fun y => y.add y

View file

@ -3,4 +3,4 @@ etaStructIssue.lean:20:2-20:5: error: type mismatch
has type
mkNat e x₁ = mkNat e x₁ : Prop
but is expected to have type
mkNat e x₁ = mkNat (E.mk e) x₂ : Prop
mkNat e x₁ = mkNat e.mk x₂ : Prop

View file

@ -1,4 +1,4 @@
Sum.someRight c : Option Nat
c.someRight : Option Nat
evalWithMVar.lean:13:6-13:21: error: don't know how to synthesize implicit argument
@Sum.someRight ?m Nat c
context:
@ -7,5 +7,5 @@ evalWithMVar.lean:13:20-13:21: error: don't know how to synthesize implicit argu
@c ?m
context:
⊢ Type ?u
Sum.someRight c : Option Nat
Sum.someRight c : Option Nat
c.someRight : Option Nat
c.someRight : Option Nat

View file

@ -4,4 +4,4 @@ constructors:
BST.leaf : ∀ {β : Type u_1}, BST Tree.leaf
BST.node : ∀ {β : Type u_1} {key : Nat} {left right : Tree β} {value : β},
ForallTree (fun k v => k < key) left →
ForallTree (fun k v => key < k) right → BST left → BST right → BST (Tree.node left key value right)
ForallTree (fun k v => key < k) right → BST left → BST right → BST (left.node key value right)

View file

@ -5,10 +5,10 @@ getElem.lean:2:2-2:6: error: failed to prove index is valid, possible solutions:
- Use `a[i]'h` notation instead, where `h` is a proof that index is valid
a : Array Nat
i : Nat
⊢ i < Array.size a
def f2 : (a : Array Nat) → Fin (Array.size a) → Nat :=
⊢ i < a.size
def f2 : (a : Array Nat) → Fin a.size → Nat :=
fun a i => a[i]
def f3 : {n : Nat} → (a : Array Nat) → n ≤ Array.size a → Fin n → Nat :=
def f3 : {n : Nat} → (a : Array Nat) → n ≤ a.size → Fin n → Nat :=
fun {n} a h i => a[i]
def f5 : (i : Nat) → i < n → Nat :=
fun i h => a[i]

View file

@ -1,15 +1,15 @@
Inferred termination argument:
termination_by n - i
Inferred termination argument:
termination_by Array.size xs - i
termination_by xs.size - i
Inferred termination argument:
termination_by Array.size xs - i
termination_by xs.size - i
Inferred termination argument:
termination_by (Array.size xs - i, Array.size ys - j)
termination_by (xs.size - i, ys.size - j)
Inferred termination argument:
termination_by (Array.size xs - i, i - j)
termination_by (xs.size - i, i - j)
Inferred termination argument:
termination_by (Array.size xs - i, i)
termination_by (xs.size - i, i)
guessLexDiff.lean:85:26-85:38: error: fail to show termination for
failure
with errors
@ -33,8 +33,8 @@ The arguments relate at each recursive call as follows:
8) 88:26-42 _ < _ _
9) 97:8-20 _ < _ _
#1: Array.size xs - i
#2: Array.size xs - (i + 1)
#1: xs.size - i
#2: xs.size - (i + 1)
Please use `termination_by` to specify a decreasing measure.
guessLexDiff.lean:102:4-102:18: error: fail to show termination for
@ -88,8 +88,8 @@ i _ _
#2 _ _
#1: Array.size xs - i
#2: Array.size xs - (i + 1)
#3: Array.size xs - i
#1: xs.size - i
#2: xs.size - (i + 1)
#3: xs.size - i
Please use `termination_by` to specify a decreasing measure.

View file

@ -3,11 +3,11 @@ guessLexFailures.lean:11:12-11:46: error: fail to show termination for
with errors
argument #1 was not used for structural recursion
failed to eliminate recursive application
nonTerminating (Nat.succ n) (Nat.succ m)
nonTerminating n.succ m.succ
argument #2 was not used for structural recursion
failed to eliminate recursive application
nonTerminating (Nat.succ n) (Nat.succ m)
nonTerminating n.succ m.succ
structural recursion cannot be used

View file

@ -1,11 +1,11 @@
inductionErrors.lean:11:12-11:27: error: unsolved goals
case lower.h
p d : Nat
⊢ p ≤ p + Nat.succ d
⊢ p ≤ p + d.succ
inductionErrors.lean:12:12-12:27: error: unsolved goals
case upper.h
q d : Nat
⊢ q + Nat.succ d > q
⊢ q + d.succ > q
inductionErrors.lean:16:19-16:26: error: unknown identifier 'elimEx2'
inductionErrors.lean:22:2-25:45: error: insufficient number of targets for 'elimEx'
inductionErrors.lean:28:16-28:23: error: unexpected eliminator resulting type

View file

@ -8,7 +8,7 @@ ys : Vec α (n + 1)
x : α
xs : Vec α n
h : Vec.cons x xs = ys
Vec.head (Vec.cons x xs) = Vec.head ys
⊢ (Vec.cons x xs).head = ys.head
inductionGen.lean:64:8-64:11: warning: declaration uses 'sorry'
case natVal
α : ExprType
@ -30,8 +30,8 @@ a✝¹ a✝ : Expr α✝
a_ih✝¹ : ∀ (b : Expr α✝), a✝¹ = b → eval (constProp a✝¹) = eval b
a_ih✝ : ∀ (b : Expr α✝), a✝ = b → eval (constProp a✝) = eval b
b : Expr ExprType.bool
h : Expr.eq a✝¹ a✝ = b
⊢ eval (constProp (Expr.eq a✝¹ a✝)) = eval b
h : a✝¹.eq a✝ = b
⊢ eval (constProp (a✝¹.eq a✝)) = eval b
case add
α : ExprType
@ -39,7 +39,7 @@ a✝¹ a✝ : Expr ExprType.nat
a_ih✝¹ : ∀ (b : Expr ExprType.nat), a✝¹ = b → eval (constProp a✝¹) = eval b
a_ih✝ : ∀ (b : Expr ExprType.nat), a✝ = b → eval (constProp a✝) = eval b
b : Expr ExprType.nat
h : Expr.add a✝¹ a✝ = b
⊢ eval (constProp (Expr.add a✝¹ a✝)) = eval b
h : a✝¹.add a✝ = b
⊢ eval (constProp (a✝¹.add a✝)) = eval b
inductionGen.lean:78:2-78:27: error: target (or one of its indices) occurs more than once
n

View file

@ -1,2 +1,2 @@
invalidPatternIssue.lean:13:0-13:20: error: invalid patterns, `x` is an explicit pattern variable, but it only occurs in positions that are inaccessible to pattern matching
{ pred := Nat.succ .(x.1) }
{ pred := .(x.1).succ }

View file

@ -3,9 +3,9 @@ Tactic is run (ideally only twice)
Tactic is run (ideally only twice)
Tactic is run (ideally only once, in most general context)
n : Nat
⊢ (invImage (fun x => x) instWellFoundedRelation).1 n (Nat.succ n)
⊢ (invImage (fun x => x) instWellFoundedRelation).1 n n.succ
Tactic is run (ideally only twice, in most general context)
Tactic is run (ideally only twice, in most general context)
n : Nat
⊢ sizeOf n < sizeOf (Nat.succ n)
n m : Nat ⊢ (invImage (fun x => PSigma.casesOn x fun a a_1 => a) instWellFoundedRelation).1 ⟨n, m + 1⟩ ⟨Nat.succ n, m⟩
⊢ sizeOf n < sizeOf n.succ
n m : Nat ⊢ (invImage (fun x => PSigma.casesOn x fun a a_1 => a) instWellFoundedRelation).1 ⟨n, m + 1⟩ ⟨n.succ, m⟩

View file

@ -15,7 +15,7 @@ a b : Nat
h : a > b
⊢ b < a
let_fun n := 5;
⟨[], ⋯⟩ : { as // List.length as ≤ 5 }
⟨[], ⋯⟩ : { as // as.length ≤ 5 }
rfl : (let_fun n := 5;
n) =
let_fun n := 5;

View file

@ -27,7 +27,7 @@ example : 0 ≠ 1 + 1 := Nat.ne_of_lt (by apply?)
example : 0 ≠ 1 + 1 := Nat.ne_of_lt (by exact Fin.size_pos')
/-- info: Try this: exact Nat.add_comm x y -/
/-- info: Try this: exact x.add_comm y -/
#guard_msgs in
example (x y : Nat) : x + y = y + x := by apply?
@ -37,7 +37,7 @@ example (n m k : Nat) : n ≤ m → n + k ≤ m + k := by apply?
/-- info: Try this: exact Nat.mul_dvd_mul_left a w -/
#guard_msgs in
example (ha : a > 0) (w : b c) : a * b a * c := by apply?
example (_ha : a > 0) (w : b c) : a * b a * c := by apply?
/-- info: Try this: Nat.lt.base x -/
#guard_msgs in
@ -46,7 +46,7 @@ example : x < x + 1 := exact?%
/-- info: Try this: exact p -/
#guard_msgs in
example (P : Prop) (p : P) : P := by apply?
/-- info: Try this: exact False.elim (np p) -/
/-- info: Try this: exact (np p).elim -/
#guard_msgs in
example (P : Prop) (p : P) (np : ¬P) : false := by apply?
/-- info: Try this: exact h x rfl -/
@ -62,19 +62,19 @@ example (α : Prop) : αα := by apply?
-- example (a b : Prop) (h : a ∧ b) : a := by apply? -- says: `exact h.left`
-- example (P Q : Prop) : (¬ Q → ¬ P) → (P → Q) := by apply? -- say: `exact Function.mtr`
/-- info: Try this: exact Nat.add_comm a b -/
/-- info: Try this: exact a.add_comm b -/
#guard_msgs in
example (a b : Nat) : a + b = b + a :=
by apply?
/-- info: Try this: exact Nat.mul_sub_left_distrib n m k -/
/-- info: Try this: exact n.mul_sub_left_distrib m k -/
#guard_msgs in
example (n m k : Nat) : n * (m - k) = n * m - n * k :=
by apply?
attribute [symm] Eq.symm
/-- info: Try this: exact Eq.symm (Nat.mul_sub_left_distrib n m k) -/
/-- info: Try this: exact (n.mul_sub_left_distrib m k).symm -/
#guard_msgs in
example (n m k : Nat) : n * m - n * k = n * (m - k) := by
apply?
@ -109,10 +109,10 @@ by apply?
example (a b : Nat) (h : a b) (w : b > 0) : b ≥ a := by apply?
-- TODO: A lemma with head symbol `¬` can be used to prove `¬ p` or `⊥`
/-- info: Try this: exact Nat.not_lt_zero a -/
/-- info: Try this: exact a.not_lt_zero -/
#guard_msgs in
example (a : Nat) : ¬ (a < 0) := by apply?
/-- info: Try this: exact Nat.not_succ_le_zero a h -/
/-- info: Try this: exact a.not_succ_le_zero h -/
#guard_msgs in
example (a : Nat) (h : a < 0) : False := by apply?
@ -165,7 +165,7 @@ axiom F (a b : Nat) : f a ≤ f b ↔ a ≤ b
#guard_msgs in
example (a b : Nat) (h : a ≤ b) : f a ≤ f b := by apply?
/-- info: Try this: exact List.join L -/
/-- info: Try this: exact L.join -/
#guard_msgs in
example (L : List (List Nat)) : List Nat := by apply? using L
@ -239,7 +239,7 @@ example {x : Int} (h : x ≠ 0) : 2 * x ≠ 0 := by
-- Check that adding `with_reducible` prevents expensive kernel reductions.
-- https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/.60exact.3F.60.20failure.3A.20.22maximum.20recursion.20depth.20has.20been.20reached.22/near/417649319
/-- info: Try this: exact Nat.add_comm n m -/
/-- info: Try this: exact n.add_comm m -/
#guard_msgs in
example (_h : List.range 10000 = List.range 10000) (n m : Nat) : n + m = m + n := by
with_reducible exact?

View file

@ -8,4 +8,4 @@ has type
String : Type
but is expected to have type
Nat : Type
Nat.succ (sorryAx Nat true) : Nat
(sorryAx Nat true).succ : Nat

View file

@ -38,7 +38,7 @@ fun x x_1 =>
fun x =>
(match (motive := Nat → Nat → Nat) x with
| 0 => id
| Nat.succ x => id)
| x.succ => id)
x : Nat → Nat
fun x =>
match x with

View file

@ -2,7 +2,7 @@ mutwf1.lean:23:2-23:6: error: unsolved goals
case h.a
n : Nat
h : n ≠ 0
Nat.sub n 0 ≠ 0
n.sub 0 ≠ 0
mutwf1.lean:33:22-33:29: error: failed to prove termination, possible solutions:
- Use `have`-expressions to prove the remaining goals
- Use `termination_by` to specify a different well-founded relation

View file

@ -1,5 +1,5 @@
phashmap_inst_coherence.lean:12:53-12:54: error: application type mismatch
PersistentHashMap.find? m
m.find?
argument
m
has type

View file

@ -1,7 +1,6 @@
Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ Nat.zero))))))) : Nat
Nat.succ
(Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ Nat.zero))))))))) : Nat
Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ ⋯)))))))) : Nat
Nat.zero.succ.succ.succ.succ.succ.succ.succ.succ : Nat
Nat.zero.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ : Nat
⋯.succ.succ.succ.succ.succ.succ.succ.succ.succ : Nat
[1, 2, 3, 4, 5, 6, 7, 8] : List Nat
[1, 2, 3, 4, 5, 6, 7, 8, ⋯] : List Nat
ppDeepTerms.lean:39:32-39:33: warning: The '⋯' token is used by the pretty printer to indicate omitted terms, and it should not be used directly. It logs this warning and then elaborates like `_`.

View file

@ -4,7 +4,7 @@ fun x x_1 =>
(fun x f x_2 =>
(match x_2, x with
| a, Nat.zero => fun x => a
| a, Nat.succ b => fun x => Nat.succ (x.fst.fst a))
| a, b.succ => fun x => (x.fst.fst a).succ)
f)
x
protected def Nat.add : Nat → Nat → Nat :=
@ -13,7 +13,7 @@ fun x x_1 =>
(fun x f x_2 =>
(match (motive := Nat → (x : Nat) → Nat.below (motive := fun x => Nat → Nat) x → Nat) x_2, x with
| a, Nat.zero => fun x => a
| a, Nat.succ b => fun x => Nat.succ (x.fst.fst a))
| a, b.succ => fun x => (x.fst.fst a).succ)
f)
x
theorem ex.{u} : ∀ {α β : Sort u} (h : α = β) (a : α), HEq (cast h a) a :=

View file

@ -4,10 +4,10 @@
[Elab.definition.body] «_aux_ppNotationCode___macroRules_term_+++__1» : Lean.Macro :=
fun x =>
let_fun __discr := x;
if Lean.Syntax.isOfKind __discr `term_+++_ = true then
let_fun __discr_1 := Lean.Syntax.getArg __discr 0;
let_fun __discr_2 := Lean.Syntax.getArg __discr 1;
let_fun __discr := Lean.Syntax.getArg __discr 2;
if __discr.isOfKind `term_+++_ = true then
let_fun __discr_1 := __discr.getArg 0;
let_fun __discr_2 := __discr.getArg 1;
let_fun __discr := __discr.getArg 2;
let_fun rhs := { raw := __discr };
let_fun lhs := { raw := __discr_1 };
do
@ -18,7 +18,7 @@
{
raw :=
Lean.Syntax.node2 info `Lean.Parser.Term.app
(Lean.Syntax.ident info (String.toSubstring' "Nat.add") (Lean.addMacroScope mainModule `Nat.add scp)
(Lean.Syntax.ident info "Nat.add".toSubstring' (Lean.addMacroScope mainModule `Nat.add scp)
[Lean.Syntax.Preresolved.decl `Nat.add [], Lean.Syntax.Preresolved.namespace `Nat.add])
(Lean.Syntax.node2 info `null lhs.raw rhs.raw) }.raw
else
@ -27,13 +27,13 @@
[Elab.definition.body] _aux_ppNotationCode___unexpand_Nat_add_1 : Lean.PrettyPrinter.Unexpander :=
fun x =>
let_fun __discr := x;
if Lean.Syntax.isOfKind __discr `Lean.Parser.Term.app = true then
let_fun __discr_1 := Lean.Syntax.getArg __discr 0;
bif false || Lean.Syntax.isOfKind __discr_1 `ident then
let_fun __discr_2 := Lean.Syntax.getArg __discr 1;
if Lean.Syntax.matchesNull __discr_2 2 = true then
let_fun __discr := Lean.Syntax.getArg __discr_2 0;
let_fun __discr_3 := Lean.Syntax.getArg __discr_2 1;
if __discr.isOfKind `Lean.Parser.Term.app = true then
let_fun __discr_1 := __discr.getArg 0;
bif false || __discr_1.isOfKind `ident then
let_fun __discr_2 := __discr.getArg 1;
if __discr_2.matchesNull 2 = true then
let_fun __discr := __discr_2.getArg 0;
let_fun __discr_3 := __discr_2.getArg 1;
let_fun rhs := { raw := __discr_3 };
let_fun lhs := { raw := __discr };
let_fun f := { raw := __discr_1 };
@ -43,11 +43,11 @@
let _ ← Lean.getMainModule
pure { raw := Lean.Syntax.node3 info `term_+++_ lhs.raw (Lean.Syntax.atom info "+++") rhs.raw }.raw
else
let_fun __discr := Lean.Syntax.getArg __discr 1;
let_fun __discr := __discr.getArg 1;
throw ()
else
let_fun __discr_2 := Lean.Syntax.getArg __discr 0;
let_fun __discr := Lean.Syntax.getArg __discr 1;
let_fun __discr_2 := __discr.getArg 0;
let_fun __discr := __discr.getArg 1;
throw ()
else
let_fun __discr := x;

View file

@ -1,6 +1,6 @@
def f : List Nat → IO Unit :=
fun xs =>
List.forM xs fun x =>
xs.forM fun x =>
if (x == 0) = true then do
IO.println "foo"
IO.println "zero"

View file

@ -2,7 +2,7 @@
as bs : List α
⊢ as ++ bs ++ bs = as ++ (bs ++ bs)
rewrite.lean:18:20-18:29: error: tactic 'rewrite' failed, did not find instance of the pattern in the target expression
List.reverse (List.reverse ?as)
?as.reverse.reverse
α : Type u_1
as bs : List α
⊢ as ++ [] ++ [] ++ bs ++ bs = as ++ (bs ++ bs)

View file

@ -19,10 +19,10 @@ def Brx.interp_nil (H: Brx a): H.interp = H.interp
}
/--
info: Brx.interp.eq_1 (n z : Term) (H_2 : Brx (Term.id2 n z)) :
Brx.interp H_2 =
info: Brx.interp.eq_1 (n z : Term) (H_2 : Brx (n.id2 z)) :
H_2.interp =
match ⋯ with
| ⋯ => Brx.interp Hz
| ⋯ => Hz.interp
-/
#guard_msgs in
#check Brx.interp.eq_1

View file

@ -12,15 +12,14 @@ attribute [simp] Formula.count_quantifiers
/--
info: Formula.count_quantifiers.eq_1.{u_1} :
∀ (x : Nat) (f₁ f₂ : Formula x),
Formula.count_quantifiers (Formula.imp f₁ f₂) = Formula.count_quantifiers f₁ + Formula.count_quantifiers f₂
∀ (x : Nat) (f₁ f₂ : Formula x), (f₁.imp f₂).count_quantifiers = f₁.count_quantifiers + f₂.count_quantifiers
-/
#guard_msgs in
#check Formula.count_quantifiers.eq_1
/--
info: Formula.count_quantifiers.eq_2.{u_1} :
∀ (x : Nat) (f : Formula (x + 1)), Formula.count_quantifiers (Formula.all f) = Formula.count_quantifiers f + 1
∀ (x : Nat) (f : Formula (x + 1)), f.all.count_quantifiers = f.count_quantifiers + 1
-/
#guard_msgs in
#check Formula.count_quantifiers.eq_2
@ -28,8 +27,8 @@ info: Formula.count_quantifiers.eq_2.{u_1} :
/--
info: Formula.count_quantifiers.eq_3.{u_1} :
∀ (x : Nat) (x_1 : Formula x),
(∀ (f₁ f₂ : Formula x), x_1 = Formula.imp f₁ f₂ → False) →
(∀ (f : Formula (x + 1)), x_1 = Formula.all f → False) → Formula.count_quantifiers x_1 = 0
(∀ (f₁ f₂ : Formula x), x_1 = f₁.imp f₂ → False) →
(∀ (f : Formula (x + 1)), x_1 = f.all → False) → x_1.count_quantifiers = 0
-/
#guard_msgs in
#check Formula.count_quantifiers.eq_3

View file

@ -1,7 +1,7 @@
attribute [simp] Array.insertionSort.swapLoop
/--
info: Array.insertionSort.swapLoop.eq_1.{u_1} {α : Type u_1} (lt : αα → Bool) (a : Array α) (h : 0 < Array.size a) :
info: Array.insertionSort.swapLoop.eq_1.{u_1} {α : Type u_1} (lt : αα → Bool) (a : Array α) (h : 0 < a.size) :
Array.insertionSort.swapLoop lt a 0 h = a
-/
#guard_msgs in
@ -9,11 +9,10 @@ info: Array.insertionSort.swapLoop.eq_1.{u_1} {α : Type u_1} (lt : αα
/--
info: Array.insertionSort.swapLoop.eq_2.{u_1} {α : Type u_1} (lt : αα → Bool) (a : Array α) (j' : Nat)
(h : Nat.succ j' < Array.size a) :
Array.insertionSort.swapLoop lt a (Nat.succ j') h =
(h : j'.succ < a.size) :
Array.insertionSort.swapLoop lt a j'.succ h =
let_fun h' := ⋯;
if lt a[Nat.succ j'] a[j'] = true then Array.insertionSort.swapLoop lt (Array.swap a ⟨Nat.succ j', h⟩ ⟨j', h'⟩) j' ⋯
else a
if lt a[j'.succ] a[j'] = true then Array.insertionSort.swapLoop lt (a.swap ⟨j'.succ, h⟩ ⟨j', h'⟩) j' ⋯ else a
-/
#guard_msgs in
#check Array.insertionSort.swapLoop.eq_2

View file

@ -81,7 +81,7 @@ set_option pp.proofs true
expecting Nat.brecOn (motive := fun x => Nat → Nat) 0 (fun x ih y => y + x) 0
#testDelab let xs := #[]; xs.push (5 : Nat)
expecting let xs : Array Nat := #[]; Array.push xs 5
expecting let xs : Array Nat := #[]; xs.push 5
#testDelab let x := Nat.zero; x + Nat.zero
expecting let x := Nat.zero; x + Nat.zero
@ -293,7 +293,7 @@ structure SubtypeLike1 {α : Sort u} (p : α → Prop) where
--Note: currently we do not try "bottom-upping" inside lambdas
--(so we will always annotate the binder type)
#testDelab SubtypeLike1 fun (x : Nat) => Nat.succ x = x
expecting SubtypeLike1 fun (x : Nat) => Nat.succ x = x
expecting SubtypeLike1 fun (x : Nat) => x.succ = x
structure SubtypeLike3 {α β γ : Sort u} (p : α → β → γ → Prop) where
@ -330,7 +330,7 @@ set_option pp.analyze.explicitHoles false in
set_option pp.analyze.trustSubtypeMk true in
#testDelab fun (n : Nat) (val : List Nat) (property : List.length val = n) => List.length { val := val, property := property : { x : List Nat // List.length x = n } }.val = n
expecting fun n val property => List.length (Subtype.val (p := fun x => List.length x = n) (⟨val, property⟩ : { x : List Nat // List.length x = n })) = n
expecting fun n val property => (Subtype.val (p := fun x => x.length = n) (⟨val, property⟩ : { x : List Nat // x.length = n })).length = n
#testDelabN Nat.brecOn
#testDelabN Nat.below
@ -358,13 +358,7 @@ set_option pp.analyze.trustSubtypeMk true in
#testDelabN Lean.PersistentHashMap.getCollisionNodeSize.match_1
#testDelabN Lean.HashMap.size.match_1
#testDelabN and_false
-- TODO: this one prints out a structure instance with keyword field `end`
set_option pp.structureInstances false in
#testDelabN Lean.Server.FileWorker.handlePlainTermGoal
-- TODO: this one desugars to a `doLet` in an assignment
set_option pp.notation false in
#testDelabN Lean.Server.FileWorker.handlePlainGoal
-- TODO: this error occurs because we use a term's type to determine `blockImplicit` (@),

View file

@ -2,9 +2,6 @@
# Delaboration of projection functions, and generalized field notation
-/
-- TODO(kmill): remove this once this is the default
set_option pp.fieldNotation.generalized true
structure A where
x : Nat
@ -40,7 +37,7 @@ end
section
/-!
Checking `pp.structureProjections` can turn off this delaborator.
Checking `pp.fieldNotation` can turn off this delaborator.
-/
set_option pp.fieldNotation false

View file

@ -15,7 +15,7 @@
#guard_msgs in
#check f.eq_3
/--
info: f.eq_4 (x_2 : Nat) (x_3 : x_2 = 99 → False) (x_4 : x_2 = 999 → False) : f (Nat.succ x_2) = f x_2
info: f.eq_4 (x_2 : Nat) (x_3 : x_2 = 99 → False) (x_4 : x_2 = 999 → False) : f x_2.succ = f x_2
-/
#guard_msgs in
#check f.eq_4

View file

@ -8,8 +8,8 @@ derive_functional_induction ackermann
/--
info: ackermann.induct (motive : Nat → Nat → Prop) (case1 : ∀ (m : Nat), motive 0 m)
(case2 : ∀ (n : Nat), motive n 1 → motive (Nat.succ n) 0)
(case3 : ∀ (n m : Nat), motive (n + 1) m → motive n (ackermann (n + 1) m) → motive (Nat.succ n) (Nat.succ m)) :
(case2 : ∀ (n : Nat), motive n 1 → motive n.succ 0)
(case3 : ∀ (n m : Nat), motive (n + 1) m → motive n (ackermann (n + 1) m) → motive n.succ m.succ) :
∀ (a a_1 : Nat), motive a a_1
-/
#guard_msgs in

View file

@ -54,22 +54,22 @@ info: Expr.typeCheck.induct (motive : Expr → Prop) (case1 : ∀ (a : Nat), mot
(case2 : ∀ (a : Bool), motive (Expr.bool a))
(case3 :
∀ (a b : Expr) (h₁ : HasType a Ty.nat) (h₂ : HasType b Ty.nat),
Expr.typeCheck b = Maybe.found Ty.nat h₂ →
Expr.typeCheck a = Maybe.found Ty.nat h₁ → motive a → motive b → motive (Expr.plus a b))
b.typeCheck = Maybe.found Ty.nat h₂ →
a.typeCheck = Maybe.found Ty.nat h₁ → motive a → motive b → motive (a.plus b))
(case4 :
∀ (a b : Expr),
(∀ (h₁ : HasType a Ty.nat) (h₂ : HasType b Ty.nat),
Expr.typeCheck a = Maybe.found Ty.nat h₁ → Expr.typeCheck b = Maybe.found Ty.nat h₂ → False) →
motive a → motive b → motive (Expr.plus a b))
a.typeCheck = Maybe.found Ty.nat h₁ → b.typeCheck = Maybe.found Ty.nat h₂ → False) →
motive a → motive b → motive (a.plus b))
(case5 :
∀ (a b : Expr) (h₁ : HasType a Ty.bool) (h₂ : HasType b Ty.bool),
Expr.typeCheck b = Maybe.found Ty.bool h₂ →
Expr.typeCheck a = Maybe.found Ty.bool h₁ → motive a → motive b → motive (Expr.and a b))
b.typeCheck = Maybe.found Ty.bool h₂ →
a.typeCheck = Maybe.found Ty.bool h₁ → motive a → motive b → motive (a.and b))
(case6 :
∀ (a b : Expr),
(∀ (h₁ : HasType a Ty.bool) (h₂ : HasType b Ty.bool),
Expr.typeCheck a = Maybe.found Ty.bool h₁ → Expr.typeCheck b = Maybe.found Ty.bool h₂ → False) →
motive a → motive b → motive (Expr.and a b))
a.typeCheck = Maybe.found Ty.bool h₁ → b.typeCheck = Maybe.found Ty.bool h₂ → False) →
motive a → motive b → motive (a.and b))
(x : Expr) : motive x
-/
#guard_msgs in

View file

@ -50,21 +50,18 @@ derive_functional_induction Finite.functions
/--
info: Finite.functions.induct (motive1 : Finite → Prop) (motive2 : (α : Type) → Finite → List α → Prop)
(case1 : motive1 Finite.unit) (case2 : motive1 Finite.bool)
(case3 : ∀ (t1 t2 : Finite), motive1 t1 → motive1 t2 → motive1 (Finite.pair t1 t2))
(case4 :
∀ (t1 t2 : Finite), motive1 t2 → motive2 (Finite.asType t2) t1 (Finite.enumerate t2) → motive1 (Finite.arr t1 t2))
(case3 : ∀ (t1 t2 : Finite), motive1 t1 → motive1 t2 → motive1 (t1.pair t2))
(case4 : ∀ (t1 t2 : Finite), motive1 t2 → motive2 t2.asType t1 t2.enumerate → motive1 (t1.arr t2))
(case5 : ∀ (α : Type) (results : List α), motive2 α Finite.unit results)
(case6 : ∀ (α : Type) (results : List α), motive2 α Finite.bool results)
(case7 :
∀ (α : Type) (results : List α) (t1 t2 : Finite),
motive2 α t2 results →
motive2 (Finite.asType t2 → α) t1 (Finite.functions t2 results) → motive2 α (Finite.pair t1 t2) results)
motive2 α t2 results → motive2 (t2.asType → α) t1 (t2.functions results) → motive2 α (t1.pair t2) results)
(case8 :
∀ (α : Type) (results : List α) (t1 t2 : Finite),
motive1 t1 →
(∀ (rest : List (Finite.asType (Finite.arr t1 t2) → α)),
motive2 (Finite.asType (Finite.arr t1 t2) → α) t2 rest) →
motive2 α (Finite.arr t1 t2) results)
(∀ (rest : List ((t1.arr t2).asType → α)), motive2 ((t1.arr t2).asType → α) t2 rest) →
motive2 α (t1.arr t2) results)
(α : Type) (t : Finite) (results : List α) : motive2 α t results
-/
#guard_msgs in

View file

@ -10,8 +10,8 @@ derive_functional_induction ackermann
/--
info: Unary.ackermann.induct (motive : Nat × Nat → Prop) (case1 : ∀ (m : Nat), motive (0, m))
(case2 : ∀ (n : Nat), motive (n, 1) → motive (Nat.succ n, 0))
(case3 : ∀ (n m : Nat), motive (n + 1, m) → motive (n, ackermann (n + 1, m)) → motive (Nat.succ n, Nat.succ m))
(case2 : ∀ (n : Nat), motive (n, 1) → motive (n.succ, 0))
(case3 : ∀ (n m : Nat), motive (n + 1, m) → motive (n, ackermann (n + 1, m)) → motive (n.succ, m.succ))
(x : Nat × Nat) : motive x
-/
#guard_msgs in
@ -30,8 +30,8 @@ derive_functional_induction ackermann
/--
info: Binary.ackermann.induct (motive : Nat → Nat → Prop) (case1 : ∀ (m : Nat), motive 0 m)
(case2 : ∀ (n : Nat), motive n 1 → motive (Nat.succ n) 0)
(case3 : ∀ (n m : Nat), motive (n + 1) m → motive n (ackermann (n + 1) m) → motive (Nat.succ n) (Nat.succ m)) :
(case2 : ∀ (n : Nat), motive n 1 → motive n.succ 0)
(case3 : ∀ (n m : Nat), motive (n + 1) m → motive n (ackermann (n + 1) m) → motive n.succ m.succ) :
∀ (a a_1 : Nat), motive a a_1
-/
#guard_msgs in
@ -64,7 +64,7 @@ termination_by n => n
derive_functional_induction fib
/--
info: fib.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : motive 1)
(case3 : ∀ (n : Nat), motive n → motive (n + 1) → motive (Nat.succ (Nat.succ n))) (x : Nat) : motive x
(case3 : ∀ (n : Nat), motive n → motive (n + 1) → motive n.succ.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check fib.induct
@ -79,8 +79,8 @@ termination_by n => n
derive_functional_induction have_tailrec
/--
info: have_tailrec.induct (motive : Nat → Prop) (case1 : motive 0)
(case2 : ∀ (n : Nat), n < n + 1 → motive n → motive (Nat.succ n)) (x : Nat) : motive x
info: have_tailrec.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : ∀ (n : Nat), n < n + 1 → motive n → motive n.succ)
(x : Nat) : motive x
-/
#guard_msgs in
#check have_tailrec.induct
@ -96,7 +96,7 @@ termination_by n => n
derive_functional_induction have_non_tailrec
/--
info: have_non_tailrec.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : ∀ (n : Nat), motive n → motive (Nat.succ n))
info: have_non_tailrec.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : ∀ (n : Nat), motive n → motive n.succ)
(x : Nat) : motive x
-/
#guard_msgs in
@ -116,7 +116,7 @@ info: let_tailrec.induct (motive : Nat → Prop) (case1 : motive 0)
(case2 :
∀ (n : Nat),
let h2 := ⋯;
motive n → motive (Nat.succ n))
motive n → motive n.succ)
(x : Nat) : motive x
-/
#guard_msgs in
@ -133,7 +133,7 @@ termination_by n => n
derive_functional_induction let_non_tailrec
/--
info: let_non_tailrec.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : ∀ (n : Nat), motive n → motive (Nat.succ n))
info: let_non_tailrec.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : ∀ (n : Nat), motive n → motive n.succ)
(x : Nat) : motive x
-/
#guard_msgs in
@ -153,8 +153,8 @@ derive_functional_induction with_ite_tailrec
/--
info: with_ite_tailrec.induct (motive : Nat → Prop) (case1 : motive 0)
(case2 : ∀ (n : Nat), n % 2 = 0 → motive n → motive (Nat.succ n))
(case3 : ∀ (n : Nat), ¬n % 2 = 0 → motive n → motive (Nat.succ n)) (x : Nat) : motive x
(case2 : ∀ (n : Nat), n % 2 = 0 → motive n → motive n.succ)
(case3 : ∀ (n : Nat), ¬n % 2 = 0 → motive n → motive n.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check with_ite_tailrec.induct
@ -175,7 +175,7 @@ derive_functional_induction with_ite_non_tailrec
/--
info: with_ite_non_tailrec.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : motive 1)
(case3 : ∀ (n : Nat), motive (n + 1) → motive n → motive (Nat.succ (Nat.succ n))) (x : Nat) : motive x
(case3 : ∀ (n : Nat), motive (n + 1) → motive n → motive n.succ.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check with_ite_non_tailrec.induct
@ -227,7 +227,7 @@ derive_functional_induction with_match_refining_tailrec
/--
info: with_match_refining_tailrec.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : motive 0 → motive (Nat.succ 0))
(case3 : ∀ (m : Nat), (m = 0 → False) → motive m → motive (Nat.succ m)) (x : Nat) : motive x
(case3 : ∀ (m : Nat), (m = 0 → False) → motive m → motive m.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check with_match_refining_tailrec.induct
@ -243,8 +243,8 @@ derive_functional_induction with_arg_refining_match1
/--
info: with_arg_refining_match1.induct (motive : Nat → Nat → Prop) (case1 : ∀ (i : Nat), motive i 0)
(case2 : ∀ (n : Nat), motive 0 (Nat.succ n))
(case3 : ∀ (i n : Nat), ¬i = 0 → motive (i - 1) n → motive i (Nat.succ n)) (i : Nat) : ∀ (a : Nat), motive i a
(case2 : ∀ (n : Nat), motive 0 n.succ) (case3 : ∀ (i n : Nat), ¬i = 0 → motive (i - 1) n → motive i n.succ)
(i : Nat) : ∀ (a : Nat), motive i a
-/
#guard_msgs in
#check with_arg_refining_match1.induct
@ -259,7 +259,7 @@ derive_functional_induction with_arg_refining_match2
/--
info: with_arg_refining_match2.induct (motive : Nat → Nat → Prop) (case1 : ∀ (n : Nat), motive 0 n)
(case2 : ∀ (i : Nat), ¬i = 0 → motive i 0)
(case3 : ∀ (i : Nat), ¬i = 0 → ∀ (n : Nat), motive (i - 1) n → motive i (Nat.succ n)) (i n : Nat) : motive i n
(case3 : ∀ (i : Nat), ¬i = 0 → ∀ (n : Nat), motive (i - 1) n → motive i n.succ) (i n : Nat) : motive i n
-/
#guard_msgs in
#check with_arg_refining_match2.induct
@ -277,8 +277,8 @@ derive_functional_induction with_other_match_tailrec
/--
info: with_other_match_tailrec.induct (motive : Nat → Prop) (case1 : motive 0)
(case2 : ∀ (n : Nat), n % 2 = 0 → motive n → motive (Nat.succ n))
(case3 : ∀ (n : Nat), (n % 2 = 0 → False) → motive n → motive (Nat.succ n)) (x : Nat) : motive x
(case2 : ∀ (n : Nat), n % 2 = 0 → motive n → motive n.succ)
(case3 : ∀ (n : Nat), (n % 2 = 0 → False) → motive n → motive n.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check with_other_match_tailrec.induct
@ -293,7 +293,7 @@ derive_functional_induction with_mixed_match_tailrec
/--
info: with_mixed_match_tailrec.induct (motive : Nat → Nat → Nat → Nat → Prop) (case1 : ∀ (a a_1 x : Nat), motive 0 x a a_1)
(case2 : ∀ (a a_1 a_2 x : Nat), motive a_2 x (a % 2) (a_1 % 2) → motive (Nat.succ a_2) x a a_1) :
(case2 : ∀ (a a_1 a_2 x : Nat), motive a_2 x (a % 2) (a_1 % 2) → motive a_2.succ x a a_1) :
∀ (a a_1 a_2 a_3 : Nat), motive a a_1 a_2 a_3
-/
#guard_msgs in
@ -312,8 +312,8 @@ derive_functional_induction with_mixed_match_tailrec2
/--
info: with_mixed_match_tailrec2.induct (motive : Nat → Nat → Nat → Nat → Nat → Prop)
(case1 : ∀ (a a_1 a_2 a_3 : Nat), motive 0 a a_1 a_2 a_3) (case2 : ∀ (a a_1 n x : Nat), motive (Nat.succ n) 0 x a a_1)
(case3 : ∀ (a a_1 n a_2 x : Nat), motive n a_2 x (a % 2) (a_1 % 2) → motive (Nat.succ n) (Nat.succ a_2) x a a_1) :
(case1 : ∀ (a a_1 a_2 a_3 : Nat), motive 0 a a_1 a_2 a_3) (case2 : ∀ (a a_1 n x : Nat), motive n.succ 0 x a a_1)
(case3 : ∀ (a a_1 n a_2 x : Nat), motive n a_2 x (a % 2) (a_1 % 2) → motive n.succ a_2.succ x a a_1) :
∀ (a a_1 a_2 a_3 a_4 : Nat), motive a a_1 a_2 a_3 a_4
-/
#guard_msgs in
@ -331,8 +331,8 @@ termination_by n => n
derive_functional_induction with_match_non_tailrec
/--
info: with_match_non_tailrec.induct (motive : Nat → Prop) (case1 : motive 0)
(case2 : ∀ (n : Nat), motive n → motive (Nat.succ n)) (x : Nat) : motive x
info: with_match_non_tailrec.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : ∀ (n : Nat), motive n → motive n.succ)
(x : Nat) : motive x
-/
#guard_msgs in
#check with_match_non_tailrec.induct
@ -355,7 +355,7 @@ info: with_match_non_tailrec_refining.induct (motive : Nat → Prop) (case1 : mo
(match n with
| 0 => motive 0
| m => motive m) →
motive (Nat.succ n))
motive n.succ)
(x : Nat) : motive x
-/
#guard_msgs in
@ -373,8 +373,8 @@ derive_functional_induction with_overlap
/--
info: with_overlap.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : motive 1) (case3 : motive 2) (case4 : motive 3)
(case5 : ∀ (n : Nat), (n = 0 → False) → (n = 1 → False) → (n = 2 → False) → motive n → motive (Nat.succ n))
(x : Nat) : motive x
(case5 : ∀ (n : Nat), (n = 0 → False) → (n = 1 → False) → (n = 2 → False) → motive n → motive n.succ) (x : Nat) :
motive x
-/
#guard_msgs in
#check with_overlap.induct
@ -392,7 +392,7 @@ derive_functional_induction unary
/--
info: UnusedExtraParams.unary.induct (base : Nat) (motive : Nat → Prop) (case1 : motive 0)
(case2 : ∀ (n : Nat), motive n → motive (Nat.succ n)) (x : Nat) : motive x
(case2 : ∀ (n : Nat), motive n → motive n.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check unary.induct
@ -405,7 +405,7 @@ derive_functional_induction binary
/--
info: UnusedExtraParams.binary.induct (base : Nat) (motive : Nat → Nat → Prop) (case1 : ∀ (m : Nat), motive 0 m)
(case2 : ∀ (n m : Nat), motive n m → motive (Nat.succ n) m) : ∀ (a a_1 : Nat), motive a a_1
(case2 : ∀ (n m : Nat), motive n m → motive n.succ m) : ∀ (a a_1 : Nat), motive a a_1
-/
#guard_msgs in
#check binary.induct
@ -441,7 +441,7 @@ info: NonTailrecMatch.match_non_tail.induct (motive : Nat → Prop)
(match x with
| 0 => True
| 1 => True
| Nat.succ (Nat.succ n) => motive n ∧ motive (n + 1)) →
| n.succ.succ => motive n ∧ motive (n + 1)) →
motive x)
(x : Nat) : motive x
-/
@ -468,7 +468,7 @@ termination_by n
derive_functional_induction foo
/--
info: AsPattern.foo.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : ∀ (n : Nat), motive n → motive (Nat.succ n))
info: AsPattern.foo.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : ∀ (n : Nat), motive n → motive n.succ)
(x : Nat) : motive x
-/
#guard_msgs in
@ -490,7 +490,7 @@ info: AsPattern.bar.induct (motive : Nat → Prop)
∀ (x : Nat),
(match x with
| 0 => True
| x@h:(Nat.succ n) => motive n) →
| x@h:n.succ => motive n) →
motive x)
(x : Nat) : motive x
-/
@ -578,8 +578,8 @@ derive_functional_induction foo
/--
info: RecCallInDisrs.foo.induct (motive : Nat → Prop) (case1 : motive 0)
(case2 : ∀ (n : Nat), foo n = 0 → motive n → motive (Nat.succ n))
(case3 : ∀ (n : Nat), ¬foo n = 0 → motive n → motive (Nat.succ n)) (x : Nat) : motive x
(case2 : ∀ (n : Nat), foo n = 0 → motive n → motive n.succ)
(case3 : ∀ (n : Nat), ¬foo n = 0 → motive n → motive n.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check foo.induct
@ -597,7 +597,7 @@ derive_functional_induction bar
/--
info: RecCallInDisrs.bar.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : bar 0 = 0 → motive 0 → motive (Nat.succ 0))
(case3 : (bar 0 = 0 → False) → motive 0 → motive (Nat.succ 0))
(case4 : ∀ (m : Nat), motive (Nat.succ m) → motive m → motive (Nat.succ (Nat.succ m))) (x : Nat) : motive x
(case4 : ∀ (m : Nat), motive m.succ → motive m → motive m.succ.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check bar.induct
@ -620,7 +620,7 @@ derive_functional_induction even
/--
info: EvenOdd.even.induct (motive1 motive2 : Nat → Prop) (case1 : motive1 0) (case2 : motive2 0)
(case3 : ∀ (n : Nat), motive2 n → motive1 (Nat.succ n)) (case4 : ∀ (n : Nat), motive1 n → motive2 (Nat.succ n)) :
(case3 : ∀ (n : Nat), motive2 n → motive1 n.succ) (case4 : ∀ (n : Nat), motive1 n → motive2 n.succ) :
∀ (a : Nat), motive1 a
-/
#guard_msgs in
@ -628,7 +628,7 @@ info: EvenOdd.even.induct (motive1 motive2 : Nat → Prop) (case1 : motive1 0) (
/--
info: EvenOdd.odd.induct (motive1 motive2 : Nat → Prop) (case1 : motive1 0) (case2 : motive2 0)
(case3 : ∀ (n : Nat), motive2 n → motive1 (Nat.succ n)) (case4 : ∀ (n : Nat), motive1 n → motive2 (Nat.succ n)) :
(case3 : ∀ (n : Nat), motive2 n → motive1 n.succ) (case4 : ∀ (n : Nat), motive1 n → motive2 n.succ) :
∀ (a : Nat), motive2 a
-/
#guard_msgs in
@ -681,7 +681,7 @@ derive_functional_induction unary
/--
info: DefaultArgument.unary.induct (fixed : Bool) (motive : Nat → Prop) (case1 : motive 0)
(case2 : ∀ (n : Nat), motive n → motive (Nat.succ n)) (x : Nat) : motive x
(case2 : ∀ (n : Nat), motive n → motive n.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check unary.induct
@ -695,7 +695,7 @@ derive_functional_induction foo
/--
info: DefaultArgument.foo.induct (fixed : Bool) (motive : Nat → Nat → Prop) (case1 : ∀ (m : Nat), motive 0 m)
(case2 : ∀ (m n : Nat), motive n m → motive (Nat.succ n) m) (n m : Nat) : motive n m
(case2 : ∀ (m n : Nat), motive n m → motive n.succ m) (n m : Nat) : motive n m
-/
#guard_msgs in
#check foo.induct
@ -719,9 +719,7 @@ info: Nary.foo.induct (motive : Nat → Nat → (k : Nat) → Fin k → Prop)
(case2 : ∀ (x x_1 : Nat) (x_2 : Fin x_1), (x = 0 → False) → motive x 0 x_1 x_2)
(case3 : ∀ (x x_1 : Nat) (x_2 : Fin 0), (x = 0 → False) → (x_1 = 0 → False) → motive x x_1 0 x_2)
(case4 : ∀ (x x_1 : Nat) (x_2 : Fin 1), (x = 0 → False) → (x_1 = 0 → False) → motive x x_1 1 x_2)
(case5 :
∀ (n m k : Nat) (x : Fin (k + 2)),
motive n m (k + 1) ⟨0, ⋯⟩ → motive (Nat.succ n) (Nat.succ m) (Nat.succ (Nat.succ k)) x) :
(case5 : ∀ (n m k : Nat) (x : Fin (k + 2)), motive n m (k + 1) ⟨0, ⋯⟩ → motive n.succ m.succ k.succ.succ x) :
∀ (a a_1 k : Nat) (a_2 : Fin k), motive a a_1 k a_2
-/
#guard_msgs in
@ -775,8 +773,8 @@ derive_functional_induction even._mutual
/--
info: CommandIdempotence.even._mutual.induct (motive : Nat ⊕' Nat → Prop) (case1 : motive (PSum.inl 0))
(case2 : motive (PSum.inr 0)) (case3 : ∀ (n : Nat), motive (PSum.inr n) → motive (PSum.inl (Nat.succ n)))
(case4 : ∀ (n : Nat), motive (PSum.inl n) → motive (PSum.inr (Nat.succ n))) (x : Nat ⊕' Nat) : motive x
(case2 : motive (PSum.inr 0)) (case3 : ∀ (n : Nat), motive (PSum.inr n) → motive (PSum.inl n.succ))
(case4 : ∀ (n : Nat), motive (PSum.inl n) → motive (PSum.inr n.succ)) (x : Nat ⊕' Nat) : motive x
-/
#guard_msgs in
#check even._mutual.induct
@ -789,15 +787,15 @@ derive_functional_induction even
/--
info: CommandIdempotence.even._mutual.induct (motive : Nat ⊕' Nat → Prop) (case1 : motive (PSum.inl 0))
(case2 : motive (PSum.inr 0)) (case3 : ∀ (n : Nat), motive (PSum.inr n) → motive (PSum.inl (Nat.succ n)))
(case4 : ∀ (n : Nat), motive (PSum.inl n) → motive (PSum.inr (Nat.succ n))) (x : Nat ⊕' Nat) : motive x
(case2 : motive (PSum.inr 0)) (case3 : ∀ (n : Nat), motive (PSum.inr n) → motive (PSum.inl n.succ))
(case4 : ∀ (n : Nat), motive (PSum.inl n) → motive (PSum.inr n.succ)) (x : Nat ⊕' Nat) : motive x
-/
#guard_msgs in
#check even._mutual.induct
/--
info: CommandIdempotence.even.induct (motive1 motive2 : Nat → Prop) (case1 : motive1 0) (case2 : motive2 0)
(case3 : ∀ (n : Nat), motive2 n → motive1 (Nat.succ n)) (case4 : ∀ (n : Nat), motive1 n → motive2 (Nat.succ n)) :
(case3 : ∀ (n : Nat), motive2 n → motive1 n.succ) (case4 : ∀ (n : Nat), motive1 n → motive2 n.succ) :
∀ (a : Nat), motive1 a
-/
#guard_msgs in
@ -856,8 +854,8 @@ derive_functional_induction foo
/--
info: PreserveParams.foo.induct (a : Nat) (motive : Nat → Prop) (case1 : motive 0)
(case2 : ∀ (n : Nat), a = 23 → motive (Nat.succ n)) (case3 : ¬a = 23 → motive (Nat.succ a))
(case4 : ∀ (n : Nat), ¬a = 23 → ¬a = n → motive n → motive (Nat.succ n)) (x : Nat) : motive x
(case2 : ∀ (n : Nat), a = 23 → motive n.succ) (case3 : ¬a = 23 → motive a.succ)
(case4 : ∀ (n : Nat), ¬a = 23 → ¬a = n → motive n → motive n.succ) (x : Nat) : motive x
-/
#guard_msgs in
#check foo.induct

View file

@ -177,11 +177,11 @@ attribute [simp] Array.heapSort.loop
/--
info: Array.heapSort.loop.eq_1.{u_1} {α : Type u_1} (lt : αα → Bool) (a : BinaryHeap α fun y x => lt x y) (out : Array α) :
Array.heapSort.loop lt a out =
match e : BinaryHeap.max a with
match e : a.max with
| none => out
| some x =>
let_fun this := ⋯;
Array.heapSort.loop lt (BinaryHeap.popMax a) (Array.push out x)
Array.heapSort.loop lt a.popMax (out.push x)
-/
#guard_msgs in
#check Array.heapSort.loop.eq_1

View file

@ -22,9 +22,7 @@ info: bla.eq_1 (y : Nat) : bla 0 y = 10
#guard_msgs in
#check bla.eq_1
/--
info: bla.eq_4 (y_2 : Nat) : bla 2 (Nat.succ y_2) = bla 2 y_2 + 1
-/
/-- info: bla.eq_4 (y_2 : Nat) : bla 2 y_2.succ = bla 2 y_2 + 1 -/
#guard_msgs in
#check bla.eq_4
@ -67,8 +65,6 @@ info: foo'.eq_2 (y : Nat) : foo' (1#3) y = 6
#guard_msgs in
#check foo'.eq_2
/--
info: foo'.eq_9 (y_2 : Nat) : foo' (7#3) (Nat.succ y_2) = foo' 7 y_2 + 1
-/
/-- info: foo'.eq_9 (y_2 : Nat) : foo' (7#3) y_2.succ = foo' 7 y_2 + 1 -/
#guard_msgs in
#check foo'.eq_9

View file

@ -6,7 +6,7 @@
#guard_msgs in
#check iota.eq_1
/-- info: iota.eq_2 (n : Nat) : iota (Nat.succ n) = Nat.succ n :: iota n -/
/-- info: iota.eq_2 (n : Nat) : iota n.succ = n.succ :: iota n -/
#guard_msgs in
#check iota.eq_2

View file

@ -1,17 +1,15 @@
/--
info: equations:
theorem List.append.eq_1.{u} : ∀ {α : Type u} (x : List α), List.append [] x = x
theorem List.append.eq_2.{u} : ∀ {α : Type u} (x : List α) (a : α) (l : List α),
List.append (a :: l) x = a :: List.append l x
theorem List.append.eq_1.{u} : ∀ {α : Type u} (x : List α), [].append x = x
theorem List.append.eq_2.{u} : ∀ {α : Type u} (x : List α) (a : α) (l : List α), (a :: l).append x = a :: l.append x
-/
#guard_msgs in
#print eqns List.append
/--
info: equations:
theorem List.append.eq_1.{u} : ∀ {α : Type u} (x : List α), List.append [] x = x
theorem List.append.eq_2.{u} : ∀ {α : Type u} (x : List α) (a : α) (l : List α),
List.append (a :: l) x = a :: List.append l x
theorem List.append.eq_1.{u} : ∀ {α : Type u} (x : List α), [].append x = x
theorem List.append.eq_2.{u} : ∀ {α : Type u} (x : List α) (a : α) (l : List α), (a :: l).append x = a :: l.append x
-/
#guard_msgs in
#print equations List.append
@ -24,8 +22,8 @@ theorem List.append.eq_2.{u} : ∀ {α : Type u} (x : List α) (a : α) (l : Lis
/--
info: equations:
theorem ack.eq_1 : ∀ (x : Nat), ack 0 x = x + 1
theorem ack.eq_2 : ∀ (x_2 : Nat), ack (Nat.succ x_2) 0 = ack x_2 1
theorem ack.eq_3 : ∀ (x_2 y : Nat), ack (Nat.succ x_2) (Nat.succ y) = ack x_2 (ack (x_2 + 1) y)
theorem ack.eq_2 : ∀ (x_2 : Nat), ack x_2.succ 0 = ack x_2 1
theorem ack.eq_3 : ∀ (x_2 y : Nat), ack x_2.succ y.succ = ack x_2 (ack (x_2 + 1) y)
-/
#guard_msgs in
#print eqns ack

View file

@ -45,7 +45,7 @@ info: fact.def :
fact x =
match x with
| 0 => 1
| Nat.succ n => (n + 1) * fact n
| n.succ => (n + 1) * fact n
-/
#guard_msgs in
#check fact.def
@ -54,7 +54,7 @@ info: fact.def :
#guard_msgs in
#check fact.eq_1
/-- info: fact.eq_2 (n : Nat) : fact (Nat.succ n) = (n + 1) * fact n -/
/-- info: fact.eq_2 (n : Nat) : fact n.succ = (n + 1) * fact n -/
#guard_msgs in
#check fact.eq_2

View file

@ -2,7 +2,7 @@
a : α
as bs : List α
h : bs = a :: as
List.length (?head :: as) = List.length bs
(?head :: as).length = bs.length
case head
α : Type ?u
@ -14,29 +14,29 @@ h : bs = a :: as
b a : α
as bs : List α
h : as = bs
List.length as + 1 + 1 = List.length bs + 2
as.length + 1 + 1 = bs.length + 2
α : Type ?u
b a : α
as bs : List α
h : as = bs
List.length as + 1 + 1 = List.length (b :: bs) + 1
as.length + 1 + 1 = (b :: bs).length + 1
α : Type ?u
b a : α
as bs : List α
h : as = bs
List.length as + 1 + 1 = List.length bs + 1 + 1
as.length + 1 + 1 = bs.length + 1 + 1
α : Type ?u
b a : α
as bs : List α
h : as = bs
⊢ id (List.length (a :: b :: as)) = List.length (b :: bs) + 1
⊢ id (a :: b :: as).length = (b :: bs).length + 1
α : Type ?u
b a : α
as bs : List α
h : as = bs
List.length (a :: b :: as) = List.length (b :: bs) + 1
⊢ (a :: b :: as).length = (b :: bs).length + 1
α : Type ?u
b a : α
as bs : List α
h : as = bs
List.length as + 1 + 1 = List.length bs + 1 + 1
as.length + 1 + 1 = bs.length + 1 + 1

View file

@ -1,3 +1,3 @@
rwWithoutOffsetCnstrs.lean:5:0-5:7: warning: declaration uses 'sorry'
m n : Nat
Nat.ble (n + 1) n = false
⊢ (n + 1).ble n = false

View file

@ -5,11 +5,11 @@ def f : Nat → Nat → Nat :=
fun x x =>
match x with
| 0 => x + 1
| Nat.succ n => x + 2
| n.succ => x + 2
fun {α_1} a => a : {α_1 : Sort u_1} → α_1 → α_1
fun x x_1 => x_1 : Nat → Nat → Nat
def f : Nat → Nat → Nat :=
fun x x_1 =>
match x_1 with
| 0 => x_1 + 1
| Nat.succ n => x_1 + 2
| n.succ => x_1 + 2

View file

@ -9,13 +9,12 @@ theorem ex1 : ∀ (x : Nat),
if f (f x) = x then 1 else y + 1) =
1 :=
fun x h =>
Eq.mpr
(id
(congrArg (fun x => x = 1)
(let_congr (Eq.refl (x * x)) fun y =>
ite_congr (Eq.trans (congrArg (fun x_1 => x_1 = x) h) (eq_self x)) (fun a => Eq.refl 1) fun a =>
Eq.refl (y + 1))))
(of_eq_true (Eq.trans (congrArg (fun x => x = 1) (ite_cond_eq_true 1 (x * x + 1) (Eq.refl True))) (eq_self 1)))
(id
(congrArg (fun x => x = 1)
(let_congr (Eq.refl (x * x)) fun y =>
ite_congr ((congrArg (fun x_1 => x_1 = x) h).trans (eq_self x)) (fun a => Eq.refl 1) fun a =>
Eq.refl (y + 1)))).mpr
(of_eq_true ((congrArg (fun x => x = 1) (ite_cond_eq_true 1 (x * x + 1) (Eq.refl True))).trans (eq_self 1)))
x z : Nat
h : f (f x) = x
h' : z = x
@ -29,8 +28,8 @@ theorem ex2 : ∀ (x z : Nat),
y) =
z :=
fun x z h h' =>
Eq.mpr (id (congrArg (fun x => x = z) (let_val_congr (fun y => y) h)))
(of_eq_true (Eq.trans (congrArg (Eq x) h') (eq_self x)))
(id (congrArg (fun x => x = z) (let_val_congr (fun y => y) h))).mpr
(of_eq_true ((congrArg (Eq x) h').trans (eq_self x)))
x z : Nat
⊢ (let α := Nat;
fun x => 0 + x) =
@ -46,5 +45,5 @@ theorem ex4 : ∀ (p : Prop),
fun x => x = x) =
fun z => p :=
fun p h =>
Eq.mpr (id (congrArg (fun x => x = fun z => p) (let_body_congr 10 fun n => funext fun x => eq_self x)))
(of_eq_true (Eq.trans (congrArg (Eq fun x => True) (funext fun z => eq_true h)) (eq_self fun x => True)))
(id (congrArg (fun x => x = fun z => p) (let_body_congr 10 fun n => funext fun x => eq_self x))).mpr
(of_eq_true ((congrArg (Eq fun x => True) (funext fun z => eq_true h)).trans (eq_self fun x => True)))

View file

@ -19,9 +19,8 @@ Try this: simp only [foo]
[Meta.Tactic.simp.rewrite] unfold foo, foo ==> 10
[Meta.Tactic.simp.rewrite] @eq_self:1000, 10 + x = 10 + x ==> True
Try this: simp only [g, pure]
[Meta.Tactic.simp.rewrite] unfold g, g x ==> Id.run
(let x := x;
pure x)
[Meta.Tactic.simp.rewrite] unfold g, g x ==> (let x := x;
pure x).run
Try this: simp (config := { unfoldPartialApp := true }) only [f1, modify, modifyGet, MonadStateOf.modifyGet,
StateT.modifyGet, pure, f2, bind, StateT.bind, get, getThe, MonadStateOf.get, StateT.get, set, StateT.set]
[Meta.Tactic.simp.rewrite] unfold f1, f1 ==> modify fun x => g x
@ -81,26 +80,26 @@ x y : Nat
α : Type
xs ys : List α
h₁ : x + x = y
h₂ : List.length xs + List.length ys = y
h₂ : xs.length + ys.length = y
⊢ x = length xs
[Meta.Tactic.simp.rewrite] unfold bla, bla x ==> match h x with
| Sum.inl (y, z) => y + z
| Sum.inr val => 0
[Meta.Tactic.simp.rewrite] unfold h, h x ==> Sum.inl (x, x)
[Meta.Tactic.simp.rewrite] @List.length_append:1000, List.length (xs ++ ys) ==> List.length xs + List.length ys
[Meta.Tactic.simp.rewrite] @List.length_append:1000, (xs ++ ys).length ==> xs.length + ys.length
Try this: simp only [bla, h, List.length_append] at *
simp_trace.lean:103:101-104:53: error: unsolved goals
x y : Nat
α : Type
xs ys : List α
h₁ : x + x = y
h₂ : List.length xs + List.length ys = y
h₂ : xs.length + ys.length = y
⊢ x = length xs
[Meta.Tactic.simp.rewrite] unfold bla, bla x ==> match h x with
| Sum.inl (y, z) => y + z
| Sum.inr val => 0
[Meta.Tactic.simp.rewrite] unfold h, h x ==> Sum.inl (x, x)
[Meta.Tactic.simp.rewrite] @List.length_append:1000, List.length (xs ++ ys) ==> List.length xs + List.length ys
[Meta.Tactic.simp.rewrite] @List.length_append:1000, (xs ++ ys).length ==> xs.length + ys.length
Try this: simp only [bla, h] at *
[Meta.Tactic.simp.rewrite] unfold bla, bla x ==> match h x with
| Sum.inl (y, z) => y + z

View file

@ -17,7 +17,7 @@ x : Nat
x : Nat
⊢ foo x = 10
x : Nat
Int.natAbs (foo x) = 10
⊢ (foo x).natAbs = 10
x : Nat
⊢ boo x
x : Nat

View file

@ -1,3 +1,3 @@
x x✝ y : Nat
h : g x = Nat.succ y
h : g x = y.succ
⊢ g x = 2 * x + 1

View file

@ -4,7 +4,7 @@ x : Nat
ih : isEven (2 * x) = true
⊢ (match 2 * (x + 1) with
| 0 => true
| Nat.succ n => isOdd n) =
| n.succ => isOdd n) =
true
case succ
x : Nat

View file

@ -1,3 +1,3 @@
unfoldReduceMatch.lean:2:0-2:7: warning: declaration uses 'sorry'
n : Nat
Nat.succ (Nat.add Nat.zero n) = Nat.succ n
(Nat.zero.add n).succ = n.succ

View file

@ -1 +1 @@
id (M.run x) : IO Unit
id x.run : IO Unit

View file

@ -6,7 +6,7 @@ fun x =>
Nat.brecOn x fun x f =>
(match (motive := (x : Nat) → Nat.below x → Nat) x with
| 0 => fun x => 1
| Nat.succ n => fun x =>
| n.succ => fun x =>
let y := 42;
2 * x.fst.fst)
f

View file

@ -1,5 +1,5 @@
def f : Nat → Nat :=
WellFounded.fix f.proof_1 fun n a =>
f.proof_1.fix fun n a =>
if h : n = 0 then 1
else
let y := 42;

View file

@ -1,7 +1,7 @@
[Meta.debug] 1. x + 1
[Meta.debug] 2. x + 1
[Meta.debug] 3. Nat.add x 1
[Meta.debug] 4. Nat.succ (Nat.add x 0)
[Meta.debug] 3. x.add 1
[Meta.debug] 4. (x.add 0).succ
[Meta.debug] 1. (x, x + 1).fst
[Meta.debug] 2. x
[Meta.debug] 3. x