Zulip Chat Archive

Stream: general

Topic: Working around the elimination restriction


Aaron Bies (Jun 10 2022 at 14:55):

As part of a homework assignment, I wrote the following script in Coq:

Require Import Lia.
Notation "'sigma' x , B" := (sigT (fun x => B))
  (at level 200, right associativity).

Definition half' : forall x, sigma y, sum (2*y = x) (2*y = S x).
Proof.
  induction x as [| x [y [h|h]]].
  - exists 0. left. reflexivity.
  - exists (S y). right. lia.
  - exists y. left. exact h.
Defined.

Definition half (x : nat) : nat :=
  match (half' x) with existT _ y _ => y end.

Eval compute in half 6. (* This prints "3" *)

I tried to translate this into Lean, but I didn't get very far.

First, I tried it just it with and , but this of course didn't make it past the elimination restriction.

def half_prop (x : ) :  y, 2 * y = x  2 * y = x + 1 :=
begin
  induction x with x ih,
  { use 0, left, refl, },

  rcases ih with y, h | h⟩,
  { use y + 1, right, rw h, refl, },
  { use y, left, exact h, },
end

def half (x : ) :  :=
begin
  cases half_prop x with y h, -- error, can only eliminate into Prop
  exact y,
end

Then, I tried using Σ and to mirror how we got around the elimination restriction in Coq...

def half' (x : ) : Σ y, (2 * y = x)  (2 * y = x + 1) :=
by sorry

...but this does not type check, because does not accept Props as arguments.

Using Σ' I got further, but once again died to the elimination restriction.

def half' (x : ) : Σ' y, (2 * y = x)  (2 * y = x + 1) :=
begin
  induction x with x ih,
  { use 0, left, refl, },

  rcases ih with y, h | h⟩, -- can only eliminate into Prop
end

Does anyone know how can I get this to work?

Junyan Xu (Jun 10 2022 at 14:57):

Instead of ⊕, use docs#psum

Riccardo Brasca (Jun 10 2022 at 15:01):

You can use classical.some (half_prop x), but maybe it's not what you want.

Riccardo Brasca (Jun 10 2022 at 15:02):

BTW half_prop should be a lemma, not a def.

Riccardo Brasca (Jun 10 2022 at 15:02):

(The linter will flag this)

Alex J. Best (Jun 10 2022 at 15:06):

Using @Junyan Xu's recommendation

import tactic
def half' (x : ) : Σ y, psum (2 * y = x)  (2 * y = x + 1) :=
begin
  induction x with x ih,
  { use 0, left, refl, },

  rcases ih with y, h | h⟩, -- can only eliminate into Prop
  { use y + 1,
    right,
    simp [mul_add, h], },
  { use y,
    left,
    exact h, },
end

Aaron Bies (Jun 10 2022 at 15:07):

Ah, it works with psum... why does it work with psum but not with sum?

Junyan Xu (Jun 10 2022 at 15:13):

psum (α : Sort u) (β : Sort v) can be applied to Prop because Prop is Sort 0.
sum (α : Type u) (β : Type v) can't be applied because Type u is Sort (u+1) so you can never get Sort 0.

Aaron Bies (Jun 10 2022 at 15:16):

Doesn't this mean one could always use psum instead of sum?

Junyan Xu (Jun 10 2022 at 15:24):

I think sum is better behaved with respect to universe level unification, because the resulting type is in Type (max u v), while psum has resulting type in Sort (max 1 u v). Is that the only reason? I don't know.

Eric Wieser (Jun 10 2022 at 15:31):

Yes, that is the reason

Aaron Bies (Jun 10 2022 at 15:53):

I need to read more about how universes work

Aaron Bies (Jun 10 2022 at 15:53):

Thank you


Last updated: Dec 20 2023 at 11:08 UTC