Matrix Coq矩阵操作

Matrix Coq矩阵操作,matrix,coq,Matrix,Coq,我试着在Coq中使用marices。我发现洛杉矶图书馆正是我所需要的,但作为Coq的新手,我无法找到证明有意义属性的方法 该库是,它定义了如下矩阵: Definition Matrix (m n : nat) := nat -> nat -> C. 现在,项目中有一些工作示例,例如: Definition V0 : Vector 2 := fun x y => match x, y with | 0, 0 => C1 |

我试着在Coq中使用marices。我发现洛杉矶图书馆正是我所需要的,但作为Coq的新手,我无法找到证明有意义属性的方法

该库是,它定义了如下矩阵:

Definition Matrix (m n : nat) := nat -> nat -> C.
现在,项目中有一些工作示例,例如:

Definition V0 : Vector 2 := 
  fun x y => match x, y with 
          | 0, 0 => C1
          | 1, 0 => C0
          | _, _ => C0
          end.
(因此
V0
是列向量(1,0))

所以我尝试的第一件事是:

Definition test : Matrix 2 2 :=
  fun x y => match x, y with
          | 0, 0 => 0
          | 0, 1 => 1
          | 1, 0 => 2
          | 1, 1 => 3
          | _, _ => 0
          end.

Definition test2 : Matrix 2 2 :=
  fun x y => match x, y with
          | 0, 0 => 0
          | 0, 1 => 2
          | 1, 0 => 4
          | 1, 1 => 6
          | _, _ => 0
          end.

Lemma double : test2 = 2 .* test. Proof. solve_matrix. Qed.
这里没有运气。于是我就试着不列举这些案例:

Lemma testouille : test2 = 2 .* test.
Proof.
  autounfold with U_db.
  prep_matrix_equality.
  assert (x = 0 \/ x = 1 \/ x >= 2)%nat as X.
  omega.
  destruct X as [X|X].
  - { (* x = 0 *)
      subst.
      assert (y = 0 \/ y = 1 \/ y >= 2)%nat as Y.
      omega.
      destruct Y as [Y|Y].
      - { (* y = 0 *)
          subst.
          simpl.
          field.
        }
      - {
          destruct Y as [Y|Y].
          - { (* y = 1 *)
              subst.
              simpl.
              field.
            }
          - { (* y >= 2 *)
              subst. (* I can't operate for each y, recursions ?*)
              simpl.
              field.
            }
        }
    }
  - { 
      destruct X as [X|X].
      - { (* x = 1 *)
          subst.
          assert (y = 0 \/ y = 1 \/ y >= 2)%nat as Y.
          omega.
          destruct Y as [Y|Y].
          - { (* y = 0 *)
              subst.
              simpl.
              field.
            }
          - {
              destruct Y as [Y|Y].
              - { (* y = 1 *)
                  subst.
                  simpl.
                  field.
                }
              - { (* y >= 2 *)
                  subst. (* I can't operate for each y, recursions ?*)
                  simpl.
                  field.
                }
            }
        }
      - { (* x >= 2, I can't operate for each x, recursions ?*)
          subst.
          simpl.
          field.
        }
    } 
Qed.

但这也不起作用,Coq似乎无法猜测如果x大于1,那么
测试xy
为零。在这一点上,我有点缺乏想法。有人能来救我吗?

看起来像是
求解矩阵
只是不知道
test
test2
要展开什么

以下是两种可能的解决方案:

Lemma double : test2 = 2 .* test. Proof. unfold test, test2. solve_matrix. Qed.

Hint Unfold test test2 : U_db.

Lemma double' : test2 = 2 .* test. Proof. solve_matrix. Qed.
对于较长的证明,您必须实际销毁
y
两次,以便Coq可以在其上进行模式匹配(您可以使用
omega
来解决其他情况)。还有一种叫做destruct_m_eq的策略,可以帮你把事情分解成不同的案例。下面是引理的一个简短的手动证明:

Lemma testouille : test2 = 2 .* test.
Proof.
  autounfold with U_db.
  prep_matrix_equality.
  unfold test, test2.
  destruct_m_eq.
  all: lca.
Qed.
与此相关,我建议使用策略
lia
lra
解决整数和实数等式,并推荐使用派生策略
lca
解决复数等式。(
字段
在您的证明中的一些实例中似乎失败。)

对于QWIRE的矩阵库(由SQIR使用)的更轻松的介绍,我推荐,尽管它确实做了一些没有反映在QWIRE主分支中的更改

Lemma double : test2 = 2 .* test. Proof. unfold test, test2. solve_matrix. Qed.

Hint Unfold test test2 : U_db.

Lemma double' : test2 = 2 .* test. Proof. solve_matrix. Qed.
Lemma testouille : test2 = 2 .* test.
Proof.
  autounfold with U_db.
  prep_matrix_equality.
  unfold test, test2.
  destruct_m_eq.
  all: lca.
Qed.