การจัดการเมทริกซ์ Coq

ฉันกำลังพยายามใช้มาริซใน Coq ฉันพบห้องสมุด la ที่ทำสิ่งที่ฉันต้องการอย่างแน่นอน แต่เนื่องจาก Coq ใหม่มาก ฉันไม่สามารถหาวิธีพิสูจน์คุณสมบัติที่มีความหมายได้

ไลบรารีคือ SQIRE และกำหนดเมทริกซ์ดังนี้:

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 I (n : nat) : Matrix n n := 
  (fun x y => if (x =? y) && (x <? n) then C1 else C0).

และ

Lemma Mmult00 : Mmult (adjoint V0) V0 = I 1. Proof. solve_matrix. Qed.

สิ่งแรกที่ฉันลองคือ:

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 แล้ว test x y จะเป็นศูนย์ และ ณ จุดนี้ ฉันยังขาดไอเดียนิดหน่อย ใครสามารถช่วยฉันได้บ้าง?


person Assombrance Andreson    schedule 04.02.2020    source แหล่งที่มา


คำตอบ (1)


ดูเหมือนว่า solve_matrix จะไม่รู้ว่า 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 สำหรับการเท่ากันของจำนวนเชิงซ้อน (field ดูเหมือนจะล้มเหลวในบางกรณีในการพิสูจน์ของคุณ)

สำหรับการแนะนำสั้นๆ เกี่ยวกับไลบรารีเมทริกซ์ของ QWIRE (ใช้โดย SQIR) ฉันขอแนะนำ Verified Quantum Computing แม้ว่าจะทำการเปลี่ยนแปลงบางอย่างที่ไม่สะท้อนให้เห็นในสาขาหลักของ QWIRE

person Rand00    schedule 04.02.2020