HoTT / Coq-HoTT

A Coq library for Homotopy Type Theory
http://homotopytypetheory.org/
Other
1.25k stars 193 forks source link

The issig tactics are slow #157

Closed JasonGross closed 11 years ago

JasonGross commented 11 years ago

The issig tactics are painfully slow for complicated record types involving three or more projections. I'm pretty sure the reason is that Coq is bad at nested sigma types, because they make the proof tree blow up. For example, by using equiv_adjointify and a lemma that proves (x.1; (x.2.1; x.2.2)) = x, I have a proof that goes through in about 2.5 seconds. (The lemma takes less than 0.1 seconds to prove.) If I don't factor out the lemma, it takes about 9 seconds to prove. If I use the issig tactic, it takes about 61 seconds to compile.

Is there a reason that we're not using equiv_adjointify in the issig tactics?

Either way, we should probably factor out the retraction(?) into separate lemmas about the eta properties of nested sigTs. I can go do this once I have an answer about using equiv_adjointify.

mikeshulman commented 11 years ago

At present we have a policy of avoiding equiv_adjointify whenever possible, because it munges the unit or counit. By avoiding equiv_adjointify, we can ensure that the unit and counit stored as part of the IsEquiv record are the exact ones we specified in the proof. However, I don't know whether this has yet been important, or whether it was just a principled decision. Why would equiv_adjointify make the issig tactics faster, though? Surely it produces an even larger proof tree, no? Is it because part of it is opaque?

JasonGross commented 11 years ago

I'm sure the opaque helps a bit, but the fact that it is folded helps significantly more. What matters is not the size of the normalized proof tree, but the size of the (unnormalized) proof tree. (I'm not sure what normalization Coq actually does; perhaps beta, iota, zeta, but certainly not delta.) Using equiv_adjointify hides more of the proof tree behind a name, and requires less construction in the presence of an already large proof tree.

mikeshulman commented 11 years ago

Surely that doesn't depend on the fact that it's equiv_adjointify we're talking about; couldn't we hide an equal amount of the proof tree behind a name in any case?

JasonGross commented 11 years ago

What's special about equiv_adjointify is that it's type is simpler. I only have to mention the fibration type once or twice, rather than n times. If you prove a similarly general lemma about the coherence of the unit and counit which doesn't depend on what record I'm dealing with, only on how many projections it has (and what they are), perhaps that would be just as good. (Perhaps there's a kind of "generalized sigma type" where we can ask for the builder, the projections, and the proofs of the elim/computation rules, and then prove something about those, and maybe that would be faster. I might try to play with this idea a bit.)

It would be great if we could replace the issig tactics with issig lemmas, which quantify over records, but Coq doesn't give us any syntax to do so. Using let ... in ... doesn't help at all. Using abstract, which I think is closest to hiding something behind a name (well, an opaque one), doesn't seem to help in this case. If you want to play with the case I'm working with, it's at https://github.com/JasonGross/HoTT-categories/blob/lax-comma-partial/theories/Comma/LaxCommaCategory.v#L130. (If my git submodule setup, or anything else, is giving you trouble, let me know.)

I don't fully understand the internals of Coq, and all of my knowledge of what is fast and slow comes from the experiences I've had with slow proofs. These are the lessons I've drawn: (I can try to elaborate on any particular one of them if you want)

mikeshulman commented 11 years ago

Apparently we have a long way to go before proof assistants are really practical for mathematics. This is the sort of thing that no user should have to think about. However, since we have to work with what we've got, and I don't think we actually have a need for specified units and counits yet, I'm fine with adjointifying in issig for now. Maybe the non-adjointifying versions could be left commented out, with comments explaining to a reader of the code that we're only adjointifying for speed reasons.

JasonGross commented 11 years ago

I agree with you that it would be nice if no-one had to think about this. I'm not sure what constitutes "really practical", and am ok with using proof assistants for, e.g., category theory as-is (though of course I have a long wish-list, with better speed fairly high up). Anyway, I'm about to make the pull request; as a side-effect, there's no more Ltac black magic in the tactics, which are much, much shorter, in addition to being faster.

mikeshulman commented 11 years ago

Yeah, a lot of the work that went into writing those tactics was due to the desire to avoid adjointifying...