# 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 `Prop`

s 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: Aug 03 2023 at 10:10 UTC