coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Agnishom Chattopadhyay <agnishom AT cmi.ac.in>
- To: coq-club AT inria.fr
- Subject: [Coq-Club] How do I manage data structures with invariants in Coq?
- Date: Tue, 10 Mar 2020 17:25:26 -0500
- Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=agnishom AT cmi.ac.in; spf=Pass smtp.mailfrom=agnishom AT cmi.ac.in; spf=None smtp.helo=postmaster AT mail.cmi.ac.in
- Ironport-phdr: 9a23:FyOQsxFQrMVTlVC0qmLHX51GYnF86YWxBRYc798ds5kLTJ78o8uwAkXT6L1XgUPTWs2DsrQY0raQ6vq4EjVduN6oizMrTt9lb1c9k8IYnggtUoauKHbQC7rUVRE8B9lIT1R//nu2YgB/Ecf6YEDO8DXptWZBUhrwOhBoKevrB4Xck9q41/yo+53Ufg5EmCexbal9IRmrogjdrNQajZV+Jqo+1xfEomZEcPlKyG11Il6egxnz6sCs8ZB57i9eoegh98lOUaX7e6Q3U7lVByk4Pm42+cPmqwDNQROA6XUAXGoWlAFIAxXe4xHhQpjxqCr6ufFj1yScIMb7UKo7WTWm76dsVR/olCIKPCM3/W3LlsB9ir9QrRS8rBJ93oHUepmYO/V+cK3Tft0UWHRPUdpKWiNbHo+xdZECA/YdMetaqYT2ulsArQG5BQmpHO7i1jBIhnn33a0h0+QhFgTG1xE+EtIOqnvUsMn1NKAKUe+v0abIzTXCYOlW2Dzg74XHaB8hofeNXbJrccrRzkwvGhjZgVWVqIzpJSma2fgXv2ia6eptTOSigHMkpQFpujWj29ogh4nTio4LxV3J9j91zJgoKdGiVUJ2YsKoHINOuy2GM4Z6WMAvTmFytCony7ALuIS3cScExZkh2hXRceaIc5KS7RLmTOuRISl3hHZieL+ngha960mgyunmWsao1VZKrzBJncPQuXwX1hzT7NCLSvp7/ki/xTaCzx3f5vxELEwui6bWJJ0szqQumpYOq0jPAyz7lFnugK+TbEok++yo6+r9YrXho5+RL5V7ig74MqQvgcy/AeM4Mg0VUmeH/OS81afv8lflT7lQj/02lLHVsIrGKsQDuq65HwhV354/5Ba4FjeqycgXnX0aLF1eYx+HlIjoO1TWIP/iF/u/glKskC1qx//cJLHhDI/NfTD/l+Lqeq844EpBwiIyy8pe7tRaEOIvOvX2D2b+st3DDhg8eye0yvr7D8102oMPUHPHVqaWNqLJsViNzukqIq+Fb8kUvmCueLAe+/fygCphyhcmdq6z0M5PMS3qLrFdO0ycJEHUrJIBHGMN51RsSeXrjBuJVD8Vbn30XqRuvmhqWrLjNp/KQ8WWuJLE2S66GpNMYWUfUwKHFHaufo7CWvFeMXvOcP8kqSQNUP2ac6FkzQun7VaowL9maOPfvCwe58ru
I am trying to implement a functional queue in Coq. My idea is to add the proof of the invariant as a part of the type. Like this:
Require Import Coq.Lists.List.
Import ListNotations.
Require Import Lia.
Section Queue.
Variable A : Type.
Record queue :=
{
front : list A;
rear : list A;
silly : list A;
invariant : length front - length rear = length silly
}.
Definition empty : queue := Build_queue [] [] [] (eq_refl).
Definition isEmpty (q : queue) : bool :=
match (front q) with
| [] => true
| _ => false
end.
Fixpoint rotate (f : list A) (r : list A) (s : list A) : list A :=
match f, r, s with
| [], (y :: _), a => y :: a
| (x :: xs), (y :: ys), a => x :: (rotate xs ys (y::a))
| _, _, _ => []
end.
Fixpoint exec (f : list A) (r : list A) (s : list A) : list A * list A * list AUTO :=
match f, r, s with
| _, _, (x :: xs) => (f, r, xs)
| _, _, [] => let f' := rotate f r [] in (f', [], f')
end.
Import ListNotations.
Require Import Lia.
Section Queue.
Variable A : Type.
Record queue :=
{
front : list A;
rear : list A;
silly : list A;
invariant : length front - length rear = length silly
}.
Definition empty : queue := Build_queue [] [] [] (eq_refl).
Definition isEmpty (q : queue) : bool :=
match (front q) with
| [] => true
| _ => false
end.
Fixpoint rotate (f : list A) (r : list A) (s : list A) : list A :=
match f, r, s with
| [], (y :: _), a => y :: a
| (x :: xs), (y :: ys), a => x :: (rotate xs ys (y::a))
| _, _, _ => []
end.
Fixpoint exec (f : list A) (r : list A) (s : list A) : list A * list A * list AUTO :=
match f, r, s with
| _, _, (x :: xs) => (f, r, xs)
| _, _, [] => let f' := rotate f r [] in (f', [], f')
end.
The following Lemma is to support the next definition
Lemma exec_preserves_invariant : forall (q : queue),
forall f r s x ,
(f, r, s) = exec (front q) (x :: rear q) (silly q)
-> length f - length r = length s.
Proof.
intros.
pose proof (invariant q).
destruct (front q); destruct (silly q).
- simpl in H. inversion H. simpl. lia.
- inversion H0.
- simpl in H. inversion H. simpl. lia.
- simpl in H. inversion H. simpl.
replace (length (a :: l)) with (S (length l)) in H0 by reflexivity.
replace (length (a0 :: l0)) with (S (length l0)) in H0 by reflexivity.
lia.
Qed.
However, I cannot figure out what would be the correct way to replace the underscore below.
Definition snoc (q : queue) (x: A) : queue :=
let ans := exec (front q) (x :: rear q) (silly q) in
let s := snd ans in
let f := fst (fst ans) in
let r := snd (fst ans) in
let inv' := (exec_preserves_invariant q f r s x _)
in
Build_queue f r s inv '.
What is the correct way to define the invariant preserving functions such as snoc?
In some languages like Lean, I have noticed that any term can be replaced by a tactic that synthesizes a similar term. So, in such a context, I could have replaced the underscore by a proof using tactics.
--Agnishom
- [Coq-Club] How do I manage data structures with invariants in Coq?, Agnishom Chattopadhyay, 03/10/2020
- Re: [Coq-Club] How do I manage data structures with invariants in Coq?, mukesh tiwari, 03/11/2020
- Re: [Coq-Club] How do I manage data structures with invariants in Coq?, Agnishom Chattopadhyay, 03/14/2020
- Re: [Coq-Club] How do I manage data structures with invariants in Coq?, mukesh tiwari, 03/14/2020
- Re: [Coq-Club] How do I manage data structures with invariants in Coq?, Dominique Larchey-Wendling, 03/14/2020
- Re: [Coq-Club] How do I manage data structures with invariants in Coq?, Agnishom Chattopadhyay, 03/14/2020
- Re: [Coq-Club] How do I manage data structures with invariants in Coq?, mukesh tiwari, 03/11/2020
Archive powered by MHonArc 2.6.18.