Zulip Chat Archive

Stream: general

Topic: dec_trivial fails with instances using `rw`


Scott Morrison (Aug 24 2019 at 02:32):

Observe the following two decidable instances, one of which uses a rewrite, and fails on most inputs, and one which avoids using the rewrite, and works just fine.

inductive T : ℕ → Prop
| t : Π {L : ℕ}, T L

def good : decidable_pred T
| L := decidable.is_true T.t

lemma T_iff (L : ℕ) : T L ↔ true :=
⟨λ h, trivial, λ h, T.t⟩

def bad : decidable_pred T
| L := by { rw T_iff, apply_instance, }

section good
local attribute [instance] good

example : T 0 := dec_trivial
end good

section bad
local attribute [instance] bad

example : T 0 := dec_trivial  -- FAILS
end bad

Scott Morrison (Aug 24 2019 at 02:33):

I suspect that this, rather than any timeout issues, is actually the root cause of most of the failures I see in trying to use dec_trivial.

Scott Morrison (Aug 24 2019 at 02:33):

Can someone explain what is going on?

Scott Morrison (Aug 24 2019 at 02:59):

(Obviously this is a minimised example; I hit this problem "in the wild", with a decidability instance where it was more painful to avoid using rewrite.)

Keeley Hoek (Aug 24 2019 at 03:01):

If you print them, you get

def good._main : @decidable_pred nat T :=
λ (a : nat), id_rhs (decidable (T a)) (@decidable.is_true (T a) (@T.t a))

vs

def bad._main : @decidable_pred nat T :=
λ (a : nat), id_rhs (decidable (T a))
    (@eq.mpr (decidable (T a)) (decidable true)
       (@id (@eq Type (decidable (T a)) (decidable true))
          (@eq.rec Prop (T a) (λ (_a : Prop), @eq Type (decidable (T a)) (decidable _a))
             (@eq.refl Type (decidable (T a)))
             true
             (@propext (T a) true (T_iff a))))
       decidable.true)

Keeley Hoek (Aug 24 2019 at 03:05):

The first one gives an is_true of the right type, along with a proof.
The second one proves that what we are deciding is the same as just deciding true, and then just says "true".

Keeley Hoek (Aug 24 2019 at 03:06):

Of course, both actually decide the question...

Keeley Hoek (Aug 24 2019 at 03:29):

The underlying problem is that

example : @ite _ (good 0) _ true false := trivial

but

example : @ite _ (bad 0)  _ true false := trivial

doesn't. I don't know if that's really any simpler, since an ite is just a rec on decidable.

Keeley Hoek (Aug 24 2019 at 03:46):

Interestingly, if I replace the ite with its definition in either of those lines, both fail.

Scott Morrison (Aug 24 2019 at 06:03):

It turns out this problem is the underlying cause of decidable instances for combinatorial games not working.

Scott Morrison (Aug 24 2019 at 06:04):

I could fix the decidable instances for the integer-valued games, but domineering seems to intrinsically involve non-definitional equations in the construction of short instances, so dec_trivial is still broken there.

Chris Hughes (Aug 24 2019 at 06:18):

It's to do with the fact that the proof of equality uses propext, and isn't a definitional equality, so the eq.rec application can't be iota reduced because the resulting expression won't type check.

Mario Carneiro (Aug 24 2019 at 06:19):

the moral of the story is to always use decidable_of_iff instead of rw to prove decidable instances. (It doesn't matter how you prove the iff)

Scott Morrison (Aug 24 2019 at 06:21):

@Mario Carneiro, I think it's worse than that. I've been investigating the decidability instances in the combinatorial games PR. By carefully avoiding rw I can now prove (0 : pgame) < 1 := dec_trivial, but dec_trivial still fails on everything involving domineering.

Scott Morrison (Aug 24 2019 at 06:23):

https://github.com/leanprover-community/mathlib/blob/surreal/src/set_theory/game/domineering.lean#L131

Mario Carneiro (Aug 24 2019 at 06:24):

The other problem I think you will run into with surreals and games is the use of well founded recursion

Mario Carneiro (Aug 24 2019 at 06:25):

You may be able to make it compute, but everything in the proof of well foundedness needs to be able to reduce, i.e. it can't be marked theorem even if it's a proof

Scott Morrison (Aug 24 2019 at 06:26):

ooh, I never knew that defining something propositional using def was any different from defining it using theorem!

Mario Carneiro (Aug 24 2019 at 06:28):

You rewrote in a proof of short? This is a bad idea and there is even a comment that says as much

Scott Morrison (Aug 24 2019 at 06:29):

You mean the unfold domineering {single_pass:=tt}?

Mario Carneiro (Aug 24 2019 at 06:29):

yes

Mario Carneiro (Aug 24 2019 at 06:29):

It's not clear to me why short is not a proposition

Mario Carneiro (Aug 24 2019 at 06:30):

at the very least you should prove it's a subsingleton

Scott Morrison (Aug 24 2019 at 06:30):

I need to get the fintypes back out of it at various points, I think.

Scott Morrison (Aug 24 2019 at 06:30):

And if I make it a Prop I can't eliminate anymore.

Mario Carneiro (Aug 24 2019 at 06:32):

is it preserved by equivalence?

Scott Morrison (Aug 24 2019 at 06:36):

Yes

Scott Morrison (Aug 24 2019 at 06:36):

oh ...

Scott Morrison (Aug 24 2019 at 06:36):

not obviously

Scott Morrison (Aug 24 2019 at 06:37):

sorry, no, it's not preserved under equivalence, I think!

Scott Morrison (Aug 24 2019 at 06:37):

You can just add infinitely many irrelevant options

Mario Carneiro (Aug 24 2019 at 06:37):

Oh but I see you have relabelling for this

Mario Carneiro (Aug 24 2019 at 06:38):

and possibly restriction too

Mario Carneiro (Aug 24 2019 at 06:39):

so you may be able to prove restriction x y -> short y -> short x

Mario Carneiro (Aug 24 2019 at 06:40):

wait no, restriction does a different thing on the left and right

Scott Morrison (Aug 24 2019 at 06:41):

restriction says that things are better for Left, and worse for Right

Scott Morrison (Aug 24 2019 at 06:41):

(err, maybe other way round)

Scott Morrison (Aug 24 2019 at 06:41):

I proved short is a subsingleton.

Scott Morrison (Aug 24 2019 at 06:42):

Why is it that you're interested in whether short is preserved by equivalence?

Scott Morrison (Aug 24 2019 at 06:42):

I think it really doesn't descend to the quotient; you could define short on the quotient by asking that there exists a pgame representative that is short.

Scott Morrison (Aug 24 2019 at 06:50):

@Mario Carneiro, do you have any advice on diagnosing non-computable problems in dec_trivial? I don't even know how to track down "the proof that is blocking reduction" in any example. (That is, all I know how to do is read everything that might be involved and look for bad smells.)

Mario Carneiro (Aug 24 2019 at 06:51):

You can use #reduce to find out what you got that isn't of_true ... or of_false ...

Mario Carneiro (Aug 24 2019 at 06:52):

In the literature they call this "canonicity", and lean doesn't have it because of axioms and irreducible proofs

Mario Carneiro (Aug 24 2019 at 06:53):

irreducible proofs aren't usually a problem because of proof irrelevance, but subsingleton eliminators like acc use a proof as their major premise, so we have to be able to reduce that proof to a constructor

Mario Carneiro (Aug 24 2019 at 06:54):

In fact whnf is sufficient, in case #reduce times out

Scott Morrison (Aug 24 2019 at 06:55):

What is it that I should be passing to whnf?

Scott Morrison (Aug 24 2019 at 06:55):

run_cmd tactic.whnf `(domineering.L ≤ 1) >>= tactic.trace

Scott Morrison (Aug 24 2019 at 06:55):

I'm missing a ...?

Mario Carneiro (Aug 24 2019 at 06:55):

the proof of decidable (domineering.L ≤ 1)

Scott Morrison (Aug 24 2019 at 06:57):

So

run_cmd tactic.whnf `(by apply_instance : decidable (domineering.L ≤ 1)) >>= tactic.trace

Scott Morrison (Aug 24 2019 at 06:57):

?

Mario Carneiro (Aug 24 2019 at 06:57):

yes, I think that should work

Mario Carneiro (Aug 24 2019 at 06:57):

does it?

Scott Morrison (Aug 24 2019 at 06:58):

Yes

Scott Morrison (Aug 24 2019 at 06:58):

it's a little long

Mario Carneiro (Aug 24 2019 at 06:59):

If it is successful, you will get a term that starts with decidable.of_true. Otherwise, you should look for the "active" part of the term; that's the head of the term unless it's a recursor, in which case you should look at the active part of the major premise, and recurse until you find something that's not a recursor

Mario Carneiro (Aug 24 2019 at 07:00):

In this case we have a recursor, decidable.rec, applied to fintype.decidable_forall_fintype in the major premise (at the end)

Mario Carneiro (Aug 24 2019 at 07:01):

so the question is, why isn't that reducing? You may need to turn on pp.implicit

Scott Morrison (Aug 24 2019 at 07:05):

pp.implicit and pp.max_steps gives me: (message too long, truncated at 262144 characters)

Scott Morrison (Aug 24 2019 at 07:06):

I guess that's what the command line is for.

Mario Carneiro (Aug 24 2019 at 07:06):

I weep for lean

Keeley Hoek (Aug 24 2019 at 07:08):

Mario, you mean is_true and is_false in your comment up there right?

Mario Carneiro (Aug 24 2019 at 07:11):

yes, I always forget the names

Scott Morrison (Aug 24 2019 at 07:11):

Hmm, the full output with pp.implicit is now at https://gist.github.com/semorrison/56f6f878a3d60d8aaee93184146fff08

Scott Morrison (Aug 24 2019 at 07:12):

but I can't find the "active part" anymore.

Scott Morrison (Aug 24 2019 at 07:12):

Unfortunately there are now 6 different appearances of fintype.decidable_forall_fintype

Scott Morrison (Aug 24 2019 at 07:16):

counting brackets tells me it's now at line 7590. :-)

Keeley Hoek (Aug 24 2019 at 07:16):

This is the worst __most fun__ thing ever

Mario Carneiro (Aug 24 2019 at 07:17):

The way I would analyze this is by manipulating the expr from lean, i.e. get the 6th subterm of the decidable.rec application, and print it

Mario Carneiro (Aug 24 2019 at 07:33):

Even without knowing the arguments to fintype.decidable_forall_fintype, it's strange to me that this would be the active term, because it's a definition. It should have unfolded

Scott Morrison (Aug 24 2019 at 07:36):

Curiously, the output has exactly four instances of eq.mpr. I think I know how to get rid of them.

Mario Carneiro (Aug 24 2019 at 07:36):

The very last thing printed is an underscore, though, suggesting that it may be stuck on a proof

Scott Morrison (Aug 24 2019 at 07:40):

Hmm, got rid of the eq.mprs, but that didn't help. Now trying pp.proofs...

Scott Morrison (Aug 24 2019 at 07:45):

Interestingly, shrinking the domineering board to a single cell causes it to reduce to is_true.


Last updated: Dec 20 2023 at 11:08 UTC