I am writing a proof of the correctness of quicksort.
My program defines a partition type, which handles the recursive partitioning step of quicksort.
Inductive partition : Type :=
| empty
| join (left: partition) (pivot: nat) (right: partition).
And a function which checks if a partition is sorted
Fixpoint p_sorted (p: partition) : bool :=
match p with
| empty => true
| join l pivot r => match l, r with
| empty, empty => true
| join _ lp _, empty => if lp <=? pivot then p_sorted l else false
| empty, join _ rp _ => if pivot <=? rp then p_sorted r else false
| join _ lp _, join _ rp _ => if (lp <=? pivot) && (pivot <=? rp) then
(p_sorted l) && (p_sorted r) else false
end
end.
I have written a Lemma with the following structure, which states that a sorted partition's left and right partitions must also be sorted. This lemma uses the "match with" syntax to break a partition apart into its left and right sub-partitions:
Lemma foo : forall (p: partition), (match p with
| empty => True
| join left pivot right => (p_sorted p = true) -> (p_sorted left = true) /\ (p_sorted right = true)
end).
Proof. (* ... proof ... *) Qed.
This lemma is already proven.
Now, I want to use it in a new proof, where the hypothesis is of the form
p_sorted x = true
How do I apply my previous lemma, to transform it into p_sorted left = true /\ p_sorted right = true
?
apply foo
fails to unify because of the pattern matching construct.