Zulip Chat Archive
Stream: general
Topic: defining a dependent function out of `fin 2`
Scott Morrison (Sep 16 2018 at 04:35):
I'm stuck on something basic to do with fin n
.
Scott Morrison (Sep 16 2018 at 04:35):
Suppose I have T : fin 2 → Type
, and I happen to have X : T ⟨ 0, by tidy ⟩
and a Y : T ⟨ 1, by tidy ⟩
.
Scott Morrison (Sep 16 2018 at 04:36):
How do I construct the dependent function Π n : fin 2, T n
which sends 0 to X
and 1 to Y
?
Simon Hudon (Sep 16 2018 at 04:36):
What about using an if _ then _ else _
?
Scott Morrison (Sep 16 2018 at 04:37):
How would that work?
Scott Morrison (Sep 16 2018 at 04:37):
I remember someone showing me a trick to do match
on fin n
, but I can't find it anywhere now. :-(
Simon Hudon (Sep 16 2018 at 04:37):
def T : fin 2 → Type | x := if x = 0 then X else Y
Simon Hudon (Sep 16 2018 at 04:38):
If you find it again, please show me.
Scott Morrison (Sep 16 2018 at 04:40):
I don't see how your suggestion helps, @Simon Hudon:
import tactic.tidy def T : fin 2 → Type := sorry def X : T ⟨ 0, by tidy ⟩ := sorry def Y : T ⟨ 1, by tidy ⟩ := sorry def S : Π n : fin 2, T n | x := if x = 0 then X else Y
Scott Morrison (Sep 16 2018 at 04:40):
errors with
type mismatch at application ite (x = 0) X term X has type T ⟨0, X._proof_1⟩ but is expected to have type T x
Simon Hudon (Sep 16 2018 at 04:41):
Ah ok, I misunderstood your problem
Scott Morrison (Sep 16 2018 at 04:47):
Here's a example of my problem:
import tactic.tidy def T : fin 2 → Type := ([ℕ, ℤ].to_array).data def X : T ⟨ 0, by tidy ⟩ := begin show ℕ, exact 1 end def Y : T ⟨ 1, by tidy ⟩ := begin show ℤ, exact -1 end def S : Π n : fin 2, T n | ⟨ 0, _ ⟩ := X | ⟨ 1, _ ⟩ := Y | _ := sorry
Scott Morrison (Sep 16 2018 at 04:47):
The question is to define S
, following the intention shown, but without a sorry
.
Scott Morrison (Sep 16 2018 at 04:47):
(Side questions include better ways to write T
in the first place.)
Simon Hudon (Sep 16 2018 at 04:47):
One thing you can do is:
def S : Π n : fin 2, T n | ⟨0,_⟩ := X | ⟨1,_⟩ := Y | ⟨succ (succ n),h⟩ := false.elim $ by { admit, }
Scott Morrison (Sep 16 2018 at 04:49):
Excellent! That works, now the question becomes --- is my distant memory that there's an even better solution, correct? :-)
Simon Hudon (Sep 16 2018 at 04:50):
My brain times out looking for one
Scott Morrison (Sep 16 2018 at 04:50):
And what is the canonical way to fill in that admit, these days?
Scott Morrison (Sep 16 2018 at 04:51):
I'd hoped that linarith
was up to proving discharging n+2 < 2
implies false
, but apparently not.
Simon Hudon (Sep 16 2018 at 04:51):
There's a linarith
tactic coming down the pipes. Maybe it can handle nat
now? We'd have to check
Simon Hudon (Sep 16 2018 at 04:51):
Oh, that's too bad
Scott Morrison (Sep 16 2018 at 04:52):
There was a recent addition saying it could do nat.
Scott Morrison (Sep 16 2018 at 04:52):
Oh, maybe I haven't pulled that one yet...
Simon Hudon (Sep 16 2018 at 04:53):
It feels like the kind of proposition that you should be able to prove in two steps. All I can think of takes more
Simon Hudon (Sep 16 2018 at 04:54):
| ⟨succ (succ n),h⟩ := false.elim $ by { apply not_lt_of_ge _ h, repeat { apply succ_le_succ <|> apply zero_le } }
Scott Morrison (Sep 16 2018 at 04:56):
(deleted)
Simon Hudon (Sep 16 2018 at 04:58):
Ah! This is even shorter:
by { repeat { have h := lt_of_succ_lt_succ h }, cases h }
Mario Carneiro (Sep 16 2018 at 05:01):
that should be false by matching
Scott Morrison (Sep 16 2018 at 05:01):
hmm, that doesn't work for me?
Scott Morrison (Sep 16 2018 at 05:01):
but Kenny just showed me:
import tactic.tidy -- import tactic.linarith def T : fin 2 → Type := ([ℕ, ℤ].to_array).data def X : T ⟨ 0, by tidy ⟩ := begin show ℕ, exact 1 end def Y : T ⟨ 1, by tidy ⟩ := begin show ℤ, exact -1 end def S : Π n : fin 2, T n | ⟨ 0, _ ⟩ := X | ⟨ 1, _ ⟩ := Y | ⟨ nat.succ (nat.succ n), H ⟩ := false.elim $ by cases H with H H; cases H with H H; cases H
Mario Carneiro (Sep 16 2018 at 05:03):
You can also use fin.succ_rec_on
to get the right induction principle
Scott Morrison (Sep 16 2018 at 05:03):
ah, and the new linarith
really does it!
Kenny Lau (Sep 16 2018 at 05:03):
how about
@[elab_as_eliminator] def fin2.rec_on {C : fin 2 → Sort*} : ∀ (n : fin 2), C 0 → C 1 → C n | ⟨0, _⟩ C0 _ := C0 | ⟨1, _⟩ _ C1 := C1 | ⟨n+2, H⟩ _ _ := false.elim $ not_le_of_gt H $ nat.le_add_left _ _
Scott Morrison (Sep 16 2018 at 05:04):
import tactic.tidy import tactic.linarith def T : fin 2 → Type := ([ℕ, ℤ].to_array).data def X : T ⟨ 0, by tidy ⟩ := begin show ℕ, exact 1 end def Y : T ⟨ 1, by tidy ⟩ := begin show ℤ, exact -1 end def S : Π n : fin 2, T n | ⟨ 0, _ ⟩ := X | ⟨ 1, _ ⟩ := Y | ⟨ n + 2, H ⟩ := by exfalso; linarith
Mario Carneiro (Sep 16 2018 at 05:13):
import data.fin data.list.basic def T : fin 2 → Type := ([ℕ, ℤ].to_array).data def X : T ⟨0, dec_trivial⟩ := (1 : ℕ) def Y : T ⟨1, dec_trivial⟩ := (-1 : ℤ) def S : Π n : fin 2, T n := fin.cases X (λ i, fin.cases Y (λ i, i.elim0) i)
Scott Morrison (Sep 16 2018 at 07:17):
Thanks, Mario. I think I might use the match
version, even if it depends on linarith, for decipherability.
Scott Morrison (Sep 16 2018 at 07:18):
I think I'll also write a fin_cases
tactic, that works with a fin n
hypothesis with n
a numeral.
Scott Morrison (Sep 16 2018 at 07:18):
(and actually gives you all the cases)
Last updated: Dec 20 2023 at 11:08 UTC