将Coq源转换为Idris有哪些有用的指导原则(例如,它们的类型系统有多相似,以及可以对翻译进行翻译)?从我收集的内容来看,伊德里斯的内置战术库很小但可扩展,所以我想有一些额外的工作,这应该是可能的。
答案 0 :(得分:5)
我最近翻译了一大块Software Foundations,并做了{P|N|Z}Arith的部分端口,我在此过程中做了一些观察:
目前通常不建议使用Idris战术(以Pruvloj
/ Elab.Reflection
形式),这种设施有点脆弱,当出现问题时很难调试。最好使用所谓的" Agda风格",尽可能依赖模式匹配。以下是更简单的Coq策略的一些粗略等价:
intros
- 只提及LHS上的变量reflexivity
- Refl
apply
- 直接调用该函数simpl
- 简化由Idris unfold
- 也为您自动完成symmetry
- sym
congruence
/ f_equal
- cong
split
- 在LHS中拆分rewrite
- rewrite ... in
rewrite <-
- rewrite sym $ ... in
rewrite in
- 要在内容中重写您可以使用replace {P=\x=>...} equation term
构造的参数。可悲的是,伊德里斯大部分时间都无法推断P
,所以这会变得有点笨重。另一个选择是将类型提取到引理中并使用rewrite
s,但这不会一直有效(例如,当replace
使一个术语的大块消失时)destruct
- 如果在单个变量上,请尝试在LHS中拆分,否则使用with
构造induction
- 在LHS中拆分并在rewrite
或直接使用递归调用。确保递归中的至少一个参数在结构上更小,或者您将失败整体并且不能将结果用作引理。对于更复杂的表达式,您还可以尝试SizeAccessible
中的Prelude.WellFounded
。trivial
- 通常等于尽可能在LHS中拆分并使用Refl
解决assert
- where
下的引理exists
- 依赖对(x ** prf)
case
- case .. of
或with
。但请注意case
- 不要在以后想要证明的事情中使用它,否则你会被rewrite
卡住(参见issue #4001) 。解决方法是制作顶级(目前您无法引用where
/ with
下的引理,请参阅issue #3991)模式匹配帮助。revert
- &#34; unintroduce&#34;通过制作一个lambda并稍后将其应用于所述变量 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