Zulip Chat Archive
Stream: general
Topic: Extra instance makes exact_dec_trivial fail
Seul Baek (Feb 18 2019 at 19:47):
Here's a simple proof by exact_dec_trivial
:
import data.list.basic def foo (n : nat) : Prop := n = 0 instance : decidable_pred foo := begin intro n, simp [foo], apply_instance end example : ∀ n ∈ [0], foo n := by tactic.exact_dec_trivial
The proof succeeds because the instance decidable_forall_mem {p : α → Prop} [decidable_pred p] (l : list α) : decidable (∀ x ∈ l, p x)
is available. Although not necessary, having an extra instance of this type does not affect the proof:
import data.list.basic def foo (n : nat) : Prop := n = 0 instance : decidable_pred foo := begin intro n, simp [foo], apply_instance end instance bar {α} {p : α → Prop} [decidable_pred p] (l : list α) : decidable (∀ x ∈ l, p x) := decidable_of_iff _ list.all_iff_forall_prop example : ∀ n ∈ [0], foo n := by tactic.exact_dec_trivial
But if you add a slightly different instance of the same type:
import data.list.basic def foo (n : nat) : Prop := n = 0 instance : decidable_pred foo := begin intro n, simp [foo], apply_instance end instance baz {α} {p : α → Prop} [decidable_pred p] (l : list α) : decidable (∀ x ∈ l, p x) := begin cases l, apply decidable.is_true, intros x h, cases h, rw list.forall_mem_cons, apply and.decidable, end example : ∀ n ∈ [0], foo n := by tactic.exact_dec_trivial
Then exact_dec_trivial
doesn't work anymore. What's the difference between bar
and baz
that causes this?
Simon Hudon (Feb 18 2019 at 19:55):
If you set the option pp.proofs
to true and #print baz
, you're going to see a proof term. Part of it is:
eq.mpr (baz._proof_2 l_hd l_tl) and.decidable
I'm wondering if, with baz._proof_2
being opaque, eq.mpr
can't unfold it to do recursion on it.
Simon Hudon (Feb 18 2019 at 19:55):
@Mario Carneiro ?
Simon Hudon (Feb 18 2019 at 19:58):
Actually, now that I look more closely at baz._proof_2
, I see that it refers to propext
which is an axiom it cannot use for computation.
Kenny Lau (Feb 18 2019 at 20:28):
don't use tactics for definitions...
Kenny Lau (Feb 18 2019 at 20:29):
I think there's a similar issue with functions defined via nat.strong_rec_on
that the kernel/VM cannot unfold proofs
Mario Carneiro (Feb 19 2019 at 00:37):
Never use rw
or cast
to construct decidable
instances
Mario Carneiro (Feb 19 2019 at 00:37):
use decidable_of_iff
instead (you can then prove the iff statement however you want)
Mario Carneiro (Feb 19 2019 at 00:38):
This is important because decidable_of_iff
does not use cast
to get from one type to another, it pattern matches on one and uses the iff statement to get to the other
Mario Carneiro (Feb 19 2019 at 00:39):
If you use rw
, it will cast across propext
and the resulting term will get stuck in reduction, even when it should be provable
Moses Schönfinkel (Feb 19 2019 at 00:40):
This should be pinned or some such, these are impossible to debug for me. The last advice I got wrt. looking into #reduce
was to put a breakpoint in C++ code :-/.
Mario Carneiro (Feb 19 2019 at 00:42):
here's the important part of the example:
set_option pp.implicit true #reduce @baz _ foo _ [0] -- @eq.rec Type (decidable (0 = 0 ∧ ∀ (x : ℕ), false → x = 0)) (λ (_x : Type), _x) -- (@is_true (0 = 0 ∧ ∀ (x : ℕ), false → x = 0) _) -- (decidable (∀ (x : ℕ), x = 0 ∨ false → x = 0)) -- (propext _)
Mario Carneiro (Feb 19 2019 at 00:43):
it's stuck on a reduction of propext
Mario Carneiro (Feb 19 2019 at 00:43):
(example slightly unelided for clarity)
Last updated: Dec 20 2023 at 11:08 UTC