问题
The authors of the book have provided proofs for some unit tests for nostutter exercise. Unfortunately, they didn't provide explanations how they work. I was able to understand all the proofs but one:
Inductive nostutter {X:Type} : list X -> Prop :=
| ns_nil : nostutter []
| ns_one : forall (x : X), nostutter [x]
| ns_cons: forall (x : X) (h : X) (t : list X), nostutter (h::t) -> x <> h -> nostutter (x::h::t).
Example test_nostutter_4: not (nostutter [3;1;1;4]).
Proof.
intro.
repeat match goal with
h: nostutter _ |- _ => inversion h; clear h; subst
end.
contradiction.
Qed.
After intro we have the following:
1 subgoal (ID 454)
H : nostutter [3; 1; 1; 4]
============================
False
When I remove repeat
and run match once, I get this:
1 subgoal (ID 519)
H2 : nostutter [1; 1; 4]
H4 : 3 <> 1
============================
False
So it tries to recursively find, where the list in H2 doesn't match any of nostutter constructors.
Can somebody explain me, how does this match work step by step? What is goal
variable and |-
symbol?
回答1:
Let me first prove this in hard way.
Example test_nostutter_4: not (nostutter [3;1;1;4]).
Proof.
intro.
(* You can think of this inversion H as
destructing nostutter [3; 1; 1; 4] into
ns_cons 3 1 [1; 4] (Trm : nostutter [1 :: 1 :: 4]) (Prf : 3 <> 1) *)
inversion H.
(* Let's invert Trm again. The process is same and I am leaving it for you to figure out*)
inversion H2.
(* At this point, you can easily that H9 say that 1 <> 1 which is off-course a false
assumption*)
unfold not in H9.
specialize (H9 eq_refl).
Print False. (* False is inductive data type with no constructor*)
inversion H9.
Qed.
As you can see that my proof has a lot of repetition, and we can easily automate them. Coq has tactic language called Ltac to combine tactics [1]. In your proof, the goal is
1 subgoal (ID 454)
H : nostutter [3; 1; 1; 4]
============================
False
and "match goal with" is pattern matching on goal. Everything at top of line (======) is assumption and below is the thing we need to prove. Rather than using line (======) to separate assumption with goal, Ltac uses turnstile (Assumption |- Goal [2]). I hope I am clear enough, but let me know if something is not clear.
[1] https://coq.inria.fr/refman/proof-engine/ltac.html#coq:tacn.match-goal
[2] https://en.wikipedia.org/wiki/Turnstile_(symbol)
来源:https://stackoverflow.com/questions/56772050/indprop-test-nostutter-4