Coq 将模式传递给战术
我正在编写一种策略,在绑定列表中查找与键关联的值。比如:Coq 将模式传递给战术,coq,coq-tactic,Coq,Coq Tactic,我正在编写一种策略,在绑定列表中查找与键关联的值。比如: Require Import String List Program. Ltac assoc needle haystack := match haystack with | @nil (_ * ?T) => constr:(@None T) | cons (?k, ?v) ?t => let pr := constr:(eq_refl k : k = needle) in constr:(Some v) |
Require Import String List Program.
Ltac assoc needle haystack :=
match haystack with
| @nil (_ * ?T) => constr:(@None T)
| cons (?k, ?v) ?t => let pr := constr:(eq_refl k : k = needle) in constr:(Some v)
| cons _ ?t => let res := assoc needle t in constr:res
end.
不幸的是,我不知道钥匙的确切形式;相反,我知道一个与之匹配的模式。更准确地说,我要寻找的关键是调用类型类方法的结果,但我事先不知道将使用哪个实例。在下面的示例中,我知道键是调用show“a”
,但我不知道使用什么实例:
Open Scope string_scope.
Open Scope list_scope.
Class Show A := { show: A -> string }.
Instance Show1 : Show string := {| show := fun x => x |}.
Instance Show2 : Show string := {| show := fun x => x ++ x |}.
Goal True.
(* Works (poses Some 1) *)
let v := assoc (show "a") [(show (Show := Show2) "a", 1); ("b", 2)] in pose v.
(* Does not work (poses None) *)
let v := assoc (show "a") [(show (Show := Show1) "a", 1); ("b", 2)] in pose v.
除了传递检查匹配的ltac
assoc
之外,还有什么技巧可以在这里使用吗?理想情况下,它看起来像是(show(show:=“a”)
,或者可能是(fun inst=>show(show:=inst)”a”)
,看起来像是传递函数,实际上:
Ltac assoc needlef haystack :=
match haystack with
| @nil (_ * ?T) => constr:(@None T)
| cons (?k, ?v) ?t => let pr := constr:(eq_refl k : k = needlef _) in constr:(Some v)
| cons _ ?t => let res := assoc needlef t in constr:res
end.
Goal False.
let v := assoc (fun i => show (Show := i) "a") [(show (Show := Show2) "a", 1); ("b", 2)] in pose v.
let v := assoc (fun i => show (Show := i) "a") [(show (Show := Show1) "a", 1); ("b", 2)] in pose v.
整洁的(我必须添加打开范围列表。
才能解析它。)