Zulip Chat Archive

Stream: lean4

Topic: induction for Prop-valued predicates


Kat Zhuchko (Aug 24 2024 at 18:44):

I am having trouble understanding how induction for Prop-valued inductive predicates
works. This is a small MWE, where Lean complains about termination to prove a simple
statement by induction, in the SimSym case of SimCong_inj:

inductive Tree where
  | Leaf : Nat  Tree
  | Plus : Tree  Tree  Tree
open Tree

inductive Sim : Tree  Tree  Prop where
  | SimCong : Sim a b
             Sim (Plus a q) (Plus b q)
  | SimRfl : Sim R R
  | SimSym : Sim R₁ R₂  Sim R₂ R₁
open Sim

theorem SimCong_inj (h : Sim (Plus a q) (Plus b q)) :
     Sim a b :=
  match h with
  | Sim.SimCong h => h
  | Sim.SimRfl => Sim.SimRfl
  | Sim.SimSym h₁ =>
    Sim.SimSym (SimCong_inj h₁)

I have then tried using induction instead of match statement, but to no avail: the inductive hypothesis given by induction does not have a usable shape and using generalizing does not
work either.

Does anyone have any hint on how to deal with this?

theorem SimCong_inj'
     (e1 : w1 = (Plus a q))
     (e2 : w2 = (Plus b q))
     (h : Sim w1 w2) :
     Sim a b := by
  induction h with
  | SimCong h ih =>
    simp at e1;
    let q1,q2 := e1;
    simp at e2;
    let q3,q4 := e2;
    subst q1 q2
    subst q3
    exact h
  | SimRfl =>
    subst e1
    simp at e2
    subst e2
    exact Sim.SimRfl
  | SimSym h ih =>
    sorry

(Style comments on the proof are also welcome! :smiling_face_with_hearts:)

Chris Bailey (Aug 24 2024 at 22:12):

The error message is quite dense, but I'm surprised how well it was able to identify the problem.

Not considering parameter h of SimCong_inj:
  its type Sim is an inductive family and indices are not variables
    Sim (a.Plus q) (b.Plus q)

So apparently it can figure it out if you make the indices variables:

theorem SimCong_inj (x y : Tree) (h : Sim x y) (h0 : x = Tree.Plus a q) (h1 : y = Tree.Plus b q):
     Sim a b :=
  match h with
  | @Sim.SimCong a' b' q' h => by
    have h2, _⟩ := Plus.injEq a' q' a q  h0
    have h3, _⟩ := Plus.injEq b' q' b q  h1
    rwa [h2, h3] at h
  | Sim.SimRfl => by
    rw [h0] at h1
    have h2, _⟩ := Plus.injEq a q b q  h1
    rw [h2]
    exact Sim.SimRfl
  | Sim.SimSym h₁ =>
    Sim.SimSym (SimCong_inj y x h₁ h1 h0)

With the way your prop is defined, SimSym is tricky. It seems to be implied by the other two constructors without changing inj. Is it acceptable to just derive it as a theorem? It should make these kinds of proofs easier.

inductive Tree where
  | Leaf : Nat  Tree
  | Plus : Tree  Tree  Tree
open Tree

inductive Sim : Tree  Tree  Prop where
  | SimCong : Sim a b  Sim (Plus a q) (Plus b q)
  | SimRfl : Sim R R
open Sim

theorem SimCong_sym {a b : Tree} : Sim a b  Sim b a
  | SimCong h2 => Sim.SimCong (SimCong_sym h2)
  | SimRfl => Sim.SimRfl

theorem SimCong_inj (a b q : Tree) : Sim (Plus a q) (Plus b q)  Sim a b
  | SimCong h2 =>  h2
  | SimRfl => Sim.SimRfl

Chris Bailey (Aug 24 2024 at 22:53):

I didn't read your inj' proof carefully, you already figured out the indices thing. When there are equality hypotheses about e.g. w1 = Plus a q, you almost always (in my experience) want to put them after the major premise (the thing you're doing induction/cases on) and not before it. In older versions it had to do with shifting those extra pieces of evidence into the motive so that they're not fixed, now I'm not sure how it gets elaborated tbh.

This particular proof seems brittle, it's accepted on 4.11.0-rc2 but not on 4.10.0

Kat Zhuchko (Aug 25 2024 at 14:34):

Removing SimSym isn't really an option because of the larger context from which this MWE was coming from... after updating to 4.11.0-rc2 now the match version with indices works, thanks! The version I updated from was 4.7.0, where match+indices was still not working. I'm not really sure why it shouldn't work with non-indices variables during the induction though... Even under 4.11.0-rc2 the induction hypothesis is unusable.


Last updated: May 02 2025 at 03:31 UTC