I'm trying to prove correctness of the queue implementation described here:
Inductive queue_type (A : Type) : Type := Queue : list A -> list A -> queue_type A.
Context {A : Type}.
Definition empty_queue : queue_type A := Queue nil nil.
Definition enqueue (queue : queue_type A) (elt : A) : queue_type A :=
match queue with Queue front back => Queue front (elt :: back) end.
Definition dequeue (queue : queue_type A) : queue_type A * option A :=
match queue with
| Queue nil nil => (queue, None)
| Queue (x :: xs) back => (Queue xs back, Some x)
| Queue nil back =>
let front := rev' back in
match front with
| (x :: xs) => (Queue xs nil, Some x)
| nil => (Queue nil nil, None) (* Dead code *)
end
end.
Definition queue_to_list (* last elt in head *) (queue : queue_type A) : list A :=
match queue with Queue front back => (back ++ rev front) end.
Definition queue_length (queue : queue_type A) : nat :=
match queue with Queue front back => List.length front + List.length back end.
One of the things I'd like to prove involves draining the queue, so I defined this function to do the computation:
Equations queue_dump_all (queue : queue_type A): list A :=
queue_dump_all queue := worker queue nil
where worker (queue': queue_type A) : list A -> list A by wf (queue_length queue') lt :=
worker queue' acc := match (dequeue queue') as deq_res return (deq_res = (dequeue queue')) -> list A with
| (queue'', Some elt) => fun pf => (worker queue'' (elt :: acc))
| _ => fun _=> acc
end _.
Reasoning with queue_dump_all is challenging, so I'm trying to prove this lemma to allow a more direct computation:
Lemma queue_dump_all_to_list: forall (queue: queue_type A), (queue_dump_all queue) = (queue_to_list queue).
I haven't been able to make progress using queue_dump_all_elim, though. I suspect the problem might be the 'manual' matching in worker instead of relying on Equation's pattern matching construct, but I had trouble with the proof of well formedness that way. Is there a way to push this proof forward?
(Originally written using Program Fixpoint but I couldn't get this answer to work either).
Here is a solution following your initial try: https://x80.org/collacoq/amugunalib.coq
The moral is: do not use
match ... with end eq_reflconstructs but rather rely onwithand theinspectpattern, Equations will then avoid getting you into dependent rewrite hell.