module Data.Fin.CaseBash whereThe case bash tacticπ
In the 1Lab, we try to strive for the most elegant proofs possible. Unfortunately, sometimes the most elegant proof really is a giant proof-by-cases. These proofs are enlightening to read and tedious to write, and are a prime candidate for proof automation.
Enter case-bash!. This tactic
walks down a goal like
and repeatedly case splits on each listable
type in the domain, and which point it gathers all of the resulting
goals into a dependent list.
Somewhat surprisingly, this can be implemented entirely using
instance arguments! We first use the Curried typeclass to gather all of the
arguments into a big Ξ£ type. We then use instance resolution to try and
find a Listing of that Ξ£-type,
which will attempt to resolve Listing instances for all of the
components. We then require proofs of the curried codomain for every
single element in the listing of the curried codomain.
case-bash!
: β {β βd βf} {Goal : Type β}
β β¦ C : Curried Goal βd βf β¦
β β¦ ds : Listing (Curried.Dom C) β¦
β All (Curried.Cod C) (Listing.univ ds)
β GoalThe type of the function is honestly more complicated then itβs implementation, which just curries and then looks up proofs in a list.
case-bash! β¦ C β¦ β¦ ds β¦ proofs =
Equiv.to (Curried.eqv C) (Ξ» ix β all-β proofs (Listing.find ds ix))Examplesπ
Now that we have our tactic, letβs see some examples. The following
bit of code proves commutativity of and via case-bash!.
private
and-comm-via-case-bash : β (x y : Bool) β and x y β‘ and y x
and-comm-via-case-bash = case-bash! (refl β· refl β· refl β· refl β· [])We can avoid writing a giant list of refl by using even more proof automation.
The decide! tactic lets us use
Dec instances to prove goals, and
All has a Dec instance that tries to decide some
predicate for every element of the list. This means that we can combine
case-bash! and decide! to discharge the entire list of
goals in one go, provided that every goal is decidable.
private
and-assoc-via-case-bash : β (x y z : Bool) β and x (and y z) β‘ and (and x y) z
and-assoc-via-case-bash = case-bash! decide!