Zulip Chat Archive

Stream: new members

Topic: How do I structure my proof?


Bbbbbbbbba (Jul 06 2024 at 00:21):

I'm doing a proof that is going to have more or less the following structure:

import Mathlib

example (a b c : Prop) (d :   Prop) (long_magic_number : )
    (ha : a  c) (hb : b  c  d long_magic_number) (hc_with_long_tactic_proof : c  d long_magic_number) (hab : a  b) : n, d n := by
  use long_magic_number
  cases hab with
  | inl h =>
    exact hc_with_long_tactic_proof (ha h)
  | inr h =>
    cases hb h with
    | inl h => exact hc_with_long_tactic_proof h
    | inr h => exact h

However, I don't like this representation because I would need to write down hc_with_long_tactic_proof (standing in for an actual long tactic proof) twice. I know I could do:

example (a b c : Prop) (d :   Prop) (long_magic_number : )
    (ha : a  c) (hb : b  c  d long_magic_number) (hc_with_long_tactic_proof : c  d long_magic_number) (hab : a  b) : n, d n := by
  use long_magic_number
  have hc : c  d long_magic_number := by exact hc_with_long_tactic_proof
  cases hab with
  | inl h =>
    exact hc (ha h)
  | inr h =>
    cases hb h with
    | inl h => exact hc h
    | inr h => exact h

But this repeats long_magic_number instead. (Really it is not just a magic number; d long_magic_number stands for some intermediate goal I got after some definition unfolding and intro and use, which has become quite hairy.)

Is there an ideal way I could structure my proof with minimal code duplication?

Bbbbbbbbba (Jul 06 2024 at 01:26):

I guess I have the "nuclear option" of using by_contra:

import Mathlib

example (a b c : Prop) (d :   Prop) (long_magic_number : )
    (ha : a  c) (hb : b  c  d long_magic_number) (hc_with_long_tactic_proof : c  d long_magic_number) (hab : a  b) : n, d n := by
  use long_magic_number
  by_contra h0
  have h1 : c := by
    cases hab with
    | inl h =>
      exact (ha h)
    | inr h =>
      cases hb h with
      | inl h => exact h
      | inr h => contradiction
  exact h0 (hc_with_long_tactic_proof h1)

And I guess if I need to further manipulate my intermediate goal, I could do apply h0 to kinda revert by_contra h0.

Michal Wallace (tangentstorm) (Jul 06 2024 at 06:04):

It kind of seems like in asking this question, you've hid away the actual problem by using short name. What's preventing you from doing that in the actual code?

Michal Wallace (tangentstorm) (Jul 06 2024 at 06:16):

Like... I'm tempted to point out that you can give a Prop (or a function to Prop) a name inside a tactic proof:

    let some_prop : Prop := Nat.Prime 4  -- doesn't have to be true
    let param_fact : Nat  Prop := λ n (0 < n)
    have : some_prop  param_fact 5 := by aesop

... But then in your example code, you're already using a short name, so I'm confused. :)

Bbbbbbbbba (Jul 07 2024 at 14:52):

Michal Wallace (tangentstorm) said:

Like... I'm tempted to point out that you can give a Prop (or a function to Prop) a name inside a tactic proof:

    let some_prop : Prop := Nat.Prime 4  -- doesn't have to be true
    let param_fact : Nat  Prop := λ n (0 < n)
    have : some_prop  param_fact 5 := by aesop

... But then in your example code, you're already using a short name, so I'm confused. :)

Which Prop are you suggesting me give a short name to? Like I said in my question, d long_magic_number stands for some intermediate goal that I have implicitly arrived at through a series of definition unfolding and intro and use, and I don't really want to write it down explicitly even once.

Bbbbbbbbba (Jul 07 2024 at 15:28):

I did find another option that feels less "nuclear" to me by using if:

import Mathlib

example (a b c : Prop) (d :   Prop) (long_magic_number : )
    (ha : a  c) (hb : b  c  d long_magic_number) (hc_with_long_tactic_proof : c  d long_magic_number) (hab : a  b) : n, d n := by
  use long_magic_number
  if hc : c then
    exact hc_with_long_tactic_proof hc
  else
    cases hab with
    | inl h =>
      exact False.elim (hc (ha h))
    | inr h =>
      cases hb h with
      | inl h => exact False.elim (hc h)
      | inr h => exact h

Last updated: May 02 2025 at 03:31 UTC