You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Ltac的操作数确定性重写与排序Coq战术开发问询

如何在Coq中实现基于规范形式的等式证明战术

我想要创建一个Coq战术,用来解决那些可以通过结合律、交换律等重写规则组合处理的等式子目标,比如证明a + b + c + d = a + (d + c) + b这类简单的和等式。

已实现的盲试交换战术

我先实现了一个盲试交换的战术,能处理简单和等式:

Require Import FMapList OrderedTypeEx List Rdefinitions Raxioms RIneq.
Open Scope R.

Ltac sort_sums_step :=
  let rec solve_sub_equality sub_equality :=
    lazymatch sub_equality with
    | ?a + ?c = ?b + ?c => solve_sub_equality (a = b)
    | ?a + ?c = ?b + ?d => rewrite (Rplus_comm (b) (d)); repeat rewrite <- (Rplus_assoc _ _ _)
    | _ => fail
    end
  in
  lazymatch goal with
  | |- ?a => solve_sub_equality a
  end.

Ltac solve_sum_equality :=
  repeat rewrite <- (Rplus_assoc _ _ _); repeat sort_sums_step; reflexivity.

Theorem TestEasyTheorem (a b c d:R) : a + b + c + d = a + (d + c) + b.
Proof.
  solve_sum_equality.
Qed.

但这个战术存在明显缺陷——它只会盲目尝试交换操作数,当等式中混合乘法、除法等复杂操作时,会因为复杂度爆炸导致计算耗时过长。因此我想开发一种更智能的战术:基于目标自动确定操作数的顺序,将等式两边都转化为唯一的规范形式,最后通过reflexivity完成证明。

已尝试的内容

生成操作数索引列表的战术

我实现了一个战术,能在给定操作数顺序时生成和中操作数的索引列表:

Ltac reverse_indices_of_left_sum_in_list l :=
  let rec id_index id lst :=
    lazymatch lst with
    | id::?q => O
    | ?a::?q => let idx1 := (id_index id q) in (constr:(S idx1))
    | _ => fail "1"
    end
  in
  let rec build_list sum_expr :=
    lazymatch sum_expr with
    | ?a + ?b => let q := (build_list a) in let idxb := (id_index b l) in (constr:(cons idxb q))
    | ?a => let idx := (id_index a l) in (constr:(cons idx nil))
    end
  in
  lazymatch goal with
  | |- ?a = ?b => let test := build_list a in pose (foo := test)
  | |- _ => fail "2"
  end.


Theorem TestEasyTheorem2 (a b c d:R) : (a + d + c + b)%R = (a + b + c + d)%R.
Proof.
  reverse_indices_of_left_sum_in_list (a::b::c::d::nil).
  (* Defines: foo := 1%nat :: 2%nat :: 3%nat :: 0%nat :: nil : list nat *)
Admitted.

尝试用索引排序和的战术

但当我尝试用索引对和进行排序时,代码执行失败:

Ltac sort_sums_step l :=
  let rec id_index id lst :=
    lazymatch lst with
    | id::?q => O
    | ?a::?q => let idx1 := (id_index id q) in (constr:(S idx1))
    | _ => fail "Identifier not found: " id
    end
  in
  let rec sort_sums sum_expr :=
    lazymatch sum_expr with
    | ?a + ?b + ?c => sort_sums (a + b) || (
      let idx_cmp := (compare (id_index b l) (id_index c l)) in
      match (eval compute in idx_cmp) with
      | Lt => fail "All good"
      | Eq => fail "All good"
      | Gt => rewrite (Rplus_assoc a b c); rewrite (Rplus_comm b c); rewrite <- (Rplus_assoc a c b)
      end)
    | ?b + ?c => let idx_cmp := compare (id_index b l) (id_index c l) in
      match (eval compute in idx_cmp) with
      | Lt => fail "All good"
      | Eq => fail "All good"
      | Gt => rewrite (Rplus_comm b c)
      end
    | ?a => fail "All good"
    end
  in
  lazymatch goal with
  | |- ?a = ?b => sort_sums a || sort_sums b
  | |- _ => fail "2"
  end.

Theorem TestEasyTheorem2 (a b c d:R) : (a + d + c + b)%R = (a + b + c + d)%R.
Proof.
  sort_sums_step (a::b::c::d::nil).

错误信息:

Variable id_index should be bound to a term but is bound to a tacvalue.

尝试自动构建操作数列表的战术

我还尝试从目标自动构建操作数列表,同样出现类似错误:

Ltac build_list :=
  let rec add_to_list id lst :=
    lazymatch lst with
    | id::?q => constr:(cons id q)
    | ?a::?q => constr:(cons a (add_to_list id q))
    | @nil => constr:(cons id nil)
    end
  in
  let rec build_id_list sum_expr lst :=
    lazymatch sum_expr with
    | ?a + ?b =>
      let lst_with_a := eval compute in (build_id_list a lst) in
      let lst_with_b := eval compute in (build_id_list b lst_with_a) in
      lst_with_b
    | ?c =>
      eval compute in (add_to_list c lst)
    end
  in
  lazymatch goal with
  | |- ?a = ?b => let bar := build_id_list a nil in let baz := (eval compute in bar) in pose (foo := baz)
  | |- _ => fail "2"
  end.

Theorem TestEasyTheorem3 (a b c:R) : a + b + c = a + c + b.
Proof.
  build_list.

错误信息:

Variable build_id_list should be bound to a term but is bound to a tacvalue.

请问在Coq中实现这种基于规范形式的等式证明战术是否可行?如果可行,该如何实现?


内容的提问来源于stack exchange,提问作者cymbaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 07:20:53