What would be some useful guidelines for converting Coq source to Idris (e.g. how similar are their type systems and what can be made of translating the proofs)? From what I gather, Idris' built-in library of tactics is minimal yet extendable, so I suppose with some extra work this should be possible.
I've recently translated a chunk of Software Foundations and did a partial port of {P|N|Z}Arith, some observations I've made in the process:
Generally using Idris tactics (in their Pruvloj
/Elab.Reflection
form) is not really recommended at the moment, this facility is somewhat fragile, and pretty hard to debug when something goes wrong. It's better to use the so-called "Agda style", relying on pattern matching where possible. Here are some rough equivalences for simpler Coq tactics:
intros
- just mention variables on the LHSreflexivity
-Refl
apply
- calling the function directlysimpl
- simplification is done automatically by Idrisunfold
- also done automatically for yousymmetry
-sym
congruence
/f_equal
-cong
split
- split in LHSrewrite
-rewrite ... in
rewrite <-
-rewrite sym $ ... in
rewrite in
- to rewrite inside something you have as a parameter you can use thereplace {P=\x=>...} equation term
construct. Sadly Idris is not able to inferP
most of the time, so this becomes a bit bulky. Another option is to extract the type into a lemma and userewrite
s, however this won't always work (e.g., whenreplace
makes a large chunk of a term disappear)destruct
- if on a single variable, try splitting in LHS, otherwise use thewith
constructinduction
- split in LHS and use a recursive call in arewrite
or directly. Make sure that at least one of arguments in recursion is structurally smaller, or you'll fail totality and won't be able to use the result as a lemma. For more complex expressions you can also trySizeAccessible
fromPrelude.WellFounded
.trivial
- usually amounts to splitting in LHS as much as possible and solving withRefl
sassert
- a lemma underwhere
exists
- dependent pair(x ** prf)
case
- eithercase .. of
orwith
. Be careful withcase
however - don't use it in anything you will later want to prove things about, otherwise you'll get stuck onrewrite
(see issue #4001). A workaround is to make top-level (currently you can't refer to lemmas underwhere
/with
, see issue #3991) pattern-matching helpers.revert
- "unintroduce" a variable by making a lambda and later applying it to said variableinversion
- manually define and use trivial lemmas about constructors:-- injectivity, used same as `cong`/`sym` FooInj : Foo a = Foo b -> a = b FooInj Refl = Refl -- disjointness, this sits in scope and is invoked when using `uninhabited`/`absurd` Uninhabited (Foo = Bar) where uninhabited Refl impossible
来源:https://stackoverflow.com/questions/23436823/converting-coq-to-idris