feat: add getBelowIndices.

This commit is contained in:
Daniel Fabian 2021-05-18 05:08:28 +00:00 committed by Leonardo de Moura
parent 91ecbb5b5c
commit ab0ef229ac
2 changed files with 44 additions and 0 deletions

View file

@ -348,6 +348,31 @@ where
mkForallFVars ys (←mkArrow premise conclusion)
(←name, mkDomain)
/-- Given a constructor name, find the indices of the corresponding `below` version thereof. -/
partial def getBelowIndices (ctorName : Name) : MetaM $ Array Nat := do
let ctorInfo ← getConstInfoCtor ctorName
let belowCtorInfo ← getConstInfoCtor (ctorName.updatePrefix $ ctorInfo.induct ++ `below)
let belowInductInfo ← getConstInfoInduct belowCtorInfo.induct
forallTelescope ctorInfo.type fun xs t => do
loop xs belowCtorInfo.type #[] 0 0
where
loop
(xs : Array Expr)
(rest : Expr)
(belowIndices : Array Nat)
(xIdx yIdx : Nat) : MetaM $ Array Nat := do
if xIdx ≥ xs.size then belowIndices else
let x := xs[xIdx]
let xTy ← inferType x
let yTy := rest.bindingDomain!
if ←isDefEq xTy yTy then
let rest ← instantiateForall rest #[x]
loop xs rest (belowIndices.push yIdx) (xIdx + 1) (yIdx + 1)
else
forallBoundedTelescope rest (some 1) fun ys rest =>
loop xs rest belowIndices xIdx (yIdx + 1)
def mkBelow (declName : Name) : MetaM Unit := do
if (←isInductivePredicate declName) then
let x ← getConstInfoInduct declName

View file

@ -1,7 +1,17 @@
import Lean
open Lean
def checkGetBelowIndices (ctorName : Name) (indices : Array Nat) : MetaM Unit := do
let actualIndices ← Meta.IndPredBelow.getBelowIndices ctorName
if actualIndices != indices then
throwError "wrong indices for {ctorName}: {actualIndices} ≟ {indices}"
namespace Ex
inductive LE : Nat → Nat → Prop
| refl : LE n n
| succ : LE n m → LE n m.succ
#eval checkGetBelowIndices ``LE.refl #[1]
#eval checkGetBelowIndices ``LE.succ #[1, 2, 3]
def typeOf {α : Sort u} (a : α) := α
@ -22,6 +32,8 @@ theorem LE.trans' : LE m n → LE n o → LE m o
inductive Even : Nat → Prop
| zero : Even 0
| ss : Even n → Even n.succ.succ
#eval checkGetBelowIndices ``Even.zero #[]
#eval checkGetBelowIndices ``Even.ss #[1, 2]
theorem Even_brecOn : typeOf @Even.brecOn = ∀ {motive : (a : Nat) → Even a → Prop} {a : Nat} (x : Even a),
(∀ (a : Nat) (x : Even a), @Even.below motive a x → motive a x) → motive a x := rfl
@ -42,6 +54,8 @@ theorem mul_left_comm (n m o : Nat) : n * (m * o) = m * (n * o) := by
inductive Power2 : Nat → Prop
| base : Power2 1
| ind : Power2 n → Power2 (2*n) -- Note that index here is not a constructor
#eval checkGetBelowIndices ``Power2.base #[]
#eval checkGetBelowIndices ``Power2.ind #[1, 2]
theorem Power2_brecOn : typeOf @Power2.brecOn = ∀ {motive : (a : Nat) → Power2 a → Prop} {a : Nat} (x : Power2 a),
(∀ (a : Nat) (x : Power2 a), @Power2.below motive a x → motive a x) → motive a x := rfl
@ -75,6 +89,9 @@ inductive step : tm → tm → Prop :=
| ST_Plus2 : ∀ n1 t2 t2',
t2 ==> t2' →
P (C n1) t2 ==> P (C n1) t2'
#eval checkGetBelowIndices ``step.ST_PlusConstConst #[1, 2]
#eval checkGetBelowIndices ``step.ST_Plus1 #[1, 2, 3, 4]
#eval checkGetBelowIndices ``step.ST_Plus2 #[1, 2, 3, 4]
def deterministic {X : Type} (R : X → X → Prop) :=
∀ x y1 y2 : X, R x y1 → R x y2 → y1 = y2
@ -96,6 +113,8 @@ axiom f : Nat → Nat
inductive is_nat : Nat -> Prop
| Z : is_nat 0
| S {n} : is_nat n → is_nat (f n)
#eval checkGetBelowIndices ``is_nat.Z #[]
#eval checkGetBelowIndices ``is_nat.S #[1, 2]
axiom P : Nat → Prop
axiom F0 : P 0