我为编译器定义了几种归纳类型,我正在验证这种形式
Inductive types := Int | Char | Symbol | Bool.
Inductive val : types -> Type :=
| T : val Bool
| F : val Bool
| Num : nat -> val Int
...
Inductive exp : types -> Type :=
| If : forall {t}, val Bool -> exp t -> exp t -> exp t
etc...
现在这很好,简化了许多事情,直到我试图证明某些定理如
Theorem example : forall t test (b1 b2 : exp t),
eval (If test b1 b2) = eval b1
\/ eval (If test b1 b2) = eval b2.
现在我想使用destruct test
进行简单的案例分析,因为只有2个案例,T
和F
需要考虑。但是,如果我尝试这个,我会收到一个错误,告诉我destruct
策略会生成错误的术语。它是做什么的。
是否有任何类似于destruct
的策略可以让我对类型合理的术语进行案例分析并自动发送那些不良类型的案例?我怀疑在这种情况下这是不可能的,处理这种证据的正确方法是什么?
答案 0 :(得分:2)
由于你没有提供你的代码,我不会试图确保它有效,但它的要点是做一个依赖的反转,传递应该使用的类型:
dependent inversion test with (
fun t v =>
match t as _t return val _t -> Prop with
| Bool => fun v => eval (If v b1 b2) = eval b1 \/ eval (If v b1 b2) = eval b2
| _ => fun v => False
end v
).
这基本上等同于编写自己的依赖模式匹配,使得with
子句中的东西存在返回注释。
这有点等同于:
refine (
match test as _test in val _t return
match _t as __t return val __t -> Prop with
| Bool => fun test => eval (If test b1 b2) = eval b1 \/ eval (If test b1 b2) = eval b2
| _ => fun _ => _t = Bool -> False
end _test
with
| T => _
| F => _
| _ => _
end
); try discriminate.