Преобразование Coq в Идрис
Каковы были бы некоторые полезные рекомендации для преобразования источника Coq в Idris (например, насколько похожи их системы типов и что можно сделать, переведя доказательства)? Из того, что я понял, встроенная библиотека тактики Идриса минимальна, но расширяема, поэтому я полагаю, что с некоторыми дополнительными усилиями это должно быть возможно.
1 ответ
Я недавно перевел часть фондов программного обеспечения и сделал частичный порт {P | N | Z} Arith, некоторые наблюдения, которые я сделал в процессе:
Вообще используя тактику Идрис (в их Pruvloj
/Elab.Reflection
form) в настоящий момент не рекомендуется, это средство несколько хрупкое, и его довольно сложно отладить, если что-то пойдет не так. Лучше использовать так называемый "стиль Агды", полагаясь на сопоставление с образцом, где это возможно. Вот некоторые грубые эквиваленты для более простой тактики Coq:
intros
- просто укажите переменные на LHSreflexivity
-Refl
apply
- вызов функции напрямуюsimpl
- Упрощение производится автоматически Идрисомunfold
- также сделано автоматически для васsymmetry
-sym
congruence
/f_equal
-cong
split
- разделить на LHSrewrite
-rewrite ... in
rewrite <-
-rewrite sym $ ... in
rewrite in
- чтобы переписать что-то, что у вас есть в качестве параметра, вы можете использоватьreplace {P=\x=>...} equation term
построить. К сожалению, Идрис не может сделать выводP
большую часть времени, так что это становится немного громоздким. Другой вариант - извлечь тип в лемму и использоватьrewrite
с, однако это не всегда работает (например, когдаreplace
делает большой кусок термина исчезнуть)destruct
- если для одной переменной, попробуйте разделить в LHS, в противном случае используйтеwith
сооружатьinduction
- разделить в LHS и использовать рекурсивный вызов вrewrite
или напрямую. Убедитесь, что хотя бы один из аргументов в рекурсии структурно меньше, иначе вы потерпите неудачу в совокупности и не сможете использовать результат в качестве леммы. Для более сложных выражений вы также можете попробоватьSizeAccessible
отPrelude.WellFounded
,trivial
- обычно сводится к расщеплению в LHS в максимально возможной степени и решению сRefl
sassert
- лемма подwhere
exists
- зависимая пара(x ** prf)
case
- илиcase .. of
или жеwith
, Будь осторожен сcase
однако - не используйте это ни в чем, о чем вы позже захотите доказать, иначе вы застрянетеrewrite
(см. выпуск № 4001). Обходной путь должен сделать на высшем уровне (в настоящее время вы не можете обратиться к леммам вwhere
/with
см. выпуск № 3991) помощники по сопоставлению с образцом.revert
- "не вводить" переменную путем создания лямбды и последующего применения ее к указанной переменнойinversion
- вручную определить и использовать тривиальные леммы о конструкторах:-- 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