From mathcomp.ssreflect
Require Import ssreflect ssrbool ssrnat eqtype ssrfun seq.
From mathcomp
Require Import path.
Require Import Eqdep.
Require Import Relation_Operators.
From fcsl
Require Import axioms pred prelude ordtype finmap pcm unionmap heap.
From DiSeL
Require Import Freshness State EqTypeX Protocols Worlds NetworkSem Rely.
From DiSeL
Require Import Actions Injection Process Always HoareTriples InferenceRules.
From DiSeL
Require Import InductiveInv While.
From DiSeL
Require Import CalculatorProtocol CalculatorInvariant.
From DiSeL
Require Import SeqLib.

Section CalculatorRecieve.

Variable l : Label.

Variable f : input -> option nat.
Variable prec : input -> bool.

Variable cs: seq nid.
Variable cls : seq nid.
(* All nodes *)
Notation nodes := (cs ++ cls).
(* All nodes are unique *)
Hypothesis Huniq : uniq nodes.

(* Protocol and its transitions *)

Notation cal := (cal_with_inv l f prec cs cls).
Notation sts := (snd_trans cal).
Notation rts := (rcv_trans cal).

Notation W := (mkWorld cal).

(* Variable d : dstatelet. *)
(* Hypothesis C : coh cal d. *)
(* Check proj2 C. *)
(* Check cal_inv_resp _ _ _ _ _ _ _ _ _ _ _ _ (proj1 C)(proj2 C). *)

Variable cl : nid.
Hypothesis  Hc : cl \in cls.

Program Definition tryrecv_resp_act := act (@tryrecv_action_wrapper W cl
      (fun k _ t b => (k == l) && (t == resp)) _).
Next Obligation. by case/andP:H=>/eqP->; rewrite domPt inE/=. Qed.

Notation loc i := (getLocal cl (getStatelet i l)).
Notation st := (ptr_nat 1).

Export CalculatorProtocol.

(* The following spec relates outstanding requests in
   pre/postconditions and also ensures that we've got the right
   answer. *)
Program Definition tryrecv_resp :
  {rs : reqs}, DHT [cl, W]
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
  (fun i => loc i = st :-> rs,
   fun (r : option perm) m =>
     match r with
     | Some (from, _, ms) =>
       let v := head 0 ms in
       let args := behead ms in
       exists rs' : reqs,
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
       [/\ loc m = st :-> rs',
        perm_eq rs ((cl, from, args) :: rs') &
        f args = Some v]
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
     | None => loc m = st :-> rs
     end) 
  := Do tryrecv_resp_act.    
Next Obligation.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (option (prod (prod nid nat) (list nat))) cl tryrecv_resp_act (@logvar (option perm) reqs (fun rs : reqs => @binarify (option perm) (fun i : state => @eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st rs)) (fun (r : option perm) (m : state) => match r as r' return (forall _ : @eq (option perm) r' r, Prop) with | Some p => let (p0, ms) as p0 return (forall _ : @eq (option perm) (@Some perm p0) r, Prop) := p in let (from, wildcard') as p1 return (forall _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) p1 ms)) r, Prop) := p0 in fun _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) (@pair nid nat from wildcard') ms)) r => @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat ms)) rs'))) (@eq (option nat) (f (@behead nat ms)) (@Some nat (@head nat O ms)))) | None => fun _ : @eq (option perm) (@None perm) r => @eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs) end (@Logic.eq_refl (option perm) r)))) *)
apply: ghC=>i1 rs L1 C.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i2 (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
apply: act_rule=>i2 R1/=; split; first by case: (rely_coh R1).
(* Goal: and3 (@eq Heap.heap (@heap_pts (list (prod (prod nat nat) (list nat))) st (remove_elem rs (@pair (prod nid nid) (list nat) (@pair nid nid cl from) (@behead nat tms)))) (@heap_pts reqs st (remove_elem rs (@pair (prod nid nat) (list nat) (@pair nid nat cl from) (@behead nat tms))))) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) (remove_elem rs (@pair (prod nid nat) (list nat) (@pair nid nat cl from) (@behead nat tms)))))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms))) *)
move=>r i3 i4[Sf]S R3/=; rewrite -(rely_loc' l R1) in L1.
(* Goal: match r as r' return (forall _ : @eq (option perm) r' r, Prop) with | Some p => let (p0, ms) as p0 return (forall _ : @eq (option perm) (@Some perm p0) r, Prop) := p in let (from, wildcard') as p1 return (forall _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) p1 ms)) r, Prop) := p0 in fun _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) (@pair nid nat from wildcard') ms)) r => @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat ms)) rs'))) (@eq (option nat) (f (@behead nat ms)) (@Some nat (@head nat O ms)))) | None => fun _ : @eq (option perm) (@None perm) r => @eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs) end (@Logic.eq_refl (option perm) r) *)
case: Sf=>_ _ _ _ /(_ l); clear C=>C.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (match zs as xs' return (forall _ : @eq (list input) xs' zs, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) zs => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') zs => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) zs)) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
case: S=>C2[|[l'][mid][tms][from][rt][pf][][E]Hin E1 Hw/=].
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
- by case=>?->Z; subst i3; rewrite (rely_loc' _ R3).
(* Goal: forall (_ : is_true (andb (@eq_op (Ordered.eqType Label) l' l) (@eq_op nat_eqType (@t_rcv (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l')) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l')) rt) Exports.resp))) (_ : @eq state i3 (@UMC.upd Label dstatelet (union_mapUMC Label dstatelet) l' (DStatelet (@UMC.upd nat_ordType Heap.heap (union_mapUMC nat_ordType Heap.heap) cl (@receive_step (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l')) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l')) rt cl from (tms_cont tms) (getStatelet i2 l') (@coh_s (mkWorld (cal_with_inv l f prec cs cls)) l' i2 C2) pf) (dstate (getStatelet i2 l'))) (consume_msg (dsoup (getStatelet i2 l')) mid)) i2)) (_ : @eq (option (prod (prod nid nat) (list nat))) r (@Some (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat from (tag tms)) (tms_cont tms)))), match r as r' return (forall _ : @eq (option perm) r' r, Prop) with | Some p2 => let (p3, ms) as p3 return (forall _ : @eq (option perm) (@Some perm p3) r, Prop) := p2 in let (from, wildcard') as p4 return (forall _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) p4 ms)) r, Prop) := p3 in fun _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) (@pair nid nat from wildcard') ms)) r => @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat ms)) rs'))) (@eq (option nat) (f (@behead nat ms)) (@Some nat (@head nat O ms)))) | None => fun _ : @eq (option perm) (@None perm) r => @eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs) end (@Logic.eq_refl (option perm) r) *)
case/andP=>/eqP Z G; subst l'; set d := (getStatelet i2 l) in C E pf Hw *.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
move=>Z->{r}; subst i3.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
move: rt pf (coh_s l C2) Hin E1 Hw R3 C G.
(* Goal: forall (rt : @receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l))) (pf : is_true (@in_mem nid cl (@mem nid (ssrbool.predPredType nid) (Protocols.Exports.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l) d)))) (coh_s : @Coherence.sort (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (getStatelet i2 l)) (_ : @InMem (@receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l))) rt (@Mem (@receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l))) (seq_PredType (@receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)))) (rcv_trans (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)))) (_ : @eq nat (tag tms) (@t_rcv (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt)) (_ : is_true (@msg_wf (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt d coh_s cl from tms)) (_ : network_rely (mkWorld (cal_with_inv l f prec cs cls)) cl (@UMC.upd Label dstatelet (union_mapUMC Label dstatelet) l (DStatelet (@UMC.upd nat_ordType Heap.heap (union_mapUMC nat_ordType Heap.heap) cl (@receive_step (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt cl from (tms_cont tms) d coh_s pf) (dstate d)) (consume_msg (dsoup d) mid)) i2) i4) (_ : @Coherence.sort (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) d) (_ : is_true (@eq_op nat_eqType (@t_rcv (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt) Exports.resp)), @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat (tms_cont tms))) rs'))) (@eq (option nat) (f (@behead nat (tms_cont tms))) (@Some nat (@head nat O (tms_cont tms))))) *)
rewrite prEq=>rt pf cohs Hin E1 Hw R3 C G.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat (tms_cont tms))) rs'))) (@eq (option nat) (f (@behead nat (tms_cont tms))) (@Some nat (@head nat O (tms_cont tms))))) *)
case: Hin=>/=Z; do?[subst rt|case: Z]=>//Z; subst rt.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat (tms_cont tms))) rs'))) (@eq (option nat) (f (@behead nat (tms_cont tms))) (@Some nat (@head nat O (tms_cont tms))))) *)
simpl in E1, Hw, R3; clear G.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
rewrite /cr_wf/= in Hw.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat (tms_cont tms))) rs'))) (@eq (option nat) (f (@behead nat (tms_cont tms))) (@Some nat (@head nat O (tms_cont tms))))) *)
case: tms E E1 R3 Hw=>t tms/= E E1 R3 Hw; subst t.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
have A1: exists s', dsoup d = mid \\-> (Msg (TMsg resp tms) from cl true) \+ s'.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
+ by move/esym/um_eta2: E=>->; exists (free mid (dsoup d)). 
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (match zs as xs' return (forall _ : @eq (list input) xs' zs, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) zs => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') zs => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) zs)) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
case: A1=>s' Es.

(* Some auxiliary facts *)
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
have Y : tms = head 0 tms :: behead tms.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
- suff M: exists x xs, tms = x::xs by case:M=>x [xs]E'; subst tms. 
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
  by case/andP: Hw=>_; case: (tms)=>//x xs _; exists x, xs.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
have Y' : from \in cs.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
- case: (proj1 C)=>Cs _ _ _. case: Cs=>Vs/(_ mid)Cs.
(* Goal: forall _ : forall _ : @eq soup (dsoup d) (@PCM.join (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage))) (@um_pts State.mid (msg TaggedMessage) mid (@Msg TaggedMessage (TMsg Exports.resp (@cons nat (@head nat O tms) (@behead nat tms))) from cl true)) s'), @eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)), @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
  rewrite Es in Vs Cs; move: (findPtUn Vs)=>Ez.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
  by move: (Cs _ Ez)=>/=; rewrite/cohMsg/==>H; case: H.

(* Using the invariant *)
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
move: ((proj2 C) (proj1 C) cl from (head 0 tms) (behead tms) mid s' Hc Y')=>//=.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
rewrite -!Y; move/(_ Es)=>F.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
rewrite Y in Hw.

(* Proving the change in permissions *)
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
have X: (cl, from, (behead tms)) \in rs.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
- by case/andP: Hw; rewrite (getStK (proj1 cohs) L1). 
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
have P1: valid (dstate d) by apply: (cohVl C).
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
have P2: valid i2 by apply: (cohS (proj2 (rely_coh R1))).
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
have P3: l \in dom i2 by rewrite -(cohD(proj2(rely_coh R1)))domPt inE/=. 
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
rewrite (rely_loc' _ R3)/= locE// /cr_step (getStK (proj1 cohs) L1)/=.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (@heap_pts (list (prod (prod nat nat) (list nat))) st (remove_elem rs (@pair (prod nid nid) (list nat) (@pair nid nid cl from) (@behead nat tms)))) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
clear R3 Hw P1 P2 P3; exists (remove_elem rs (cl, from, (behead tms))). 
(* Goal: and3 (@eq Heap.heap (@heap_pts (list (prod (prod nat nat) (list nat))) st (remove_elem rs (@pair (prod nid nid) (list nat) (@pair nid nid cl from) (@behead nat tms)))) (@heap_pts reqs st (remove_elem rs (@pair (prod nid nat) (list nat) (@pair nid nat cl from) (@behead nat tms))))) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) (remove_elem rs (@pair (prod nid nat) (list nat) (@pair nid nat cl from) (@behead nat tms)))))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms))) *)
move: (remove_elem_in rs (cl, from, (behead tms))); rewrite X.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
by rewrite perm_eq_sym=>H.
Qed.


Definition receive_loop_cond (res : option nat) := res == None .

Definition receive_loop_inv (rs : reqs) :=
  fun r i =>
    match r with
     | Some v =>
       exists (rs' : reqs) from args ,
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
       [/\ loc i = st :-> rs',
        perm_eq rs ((cl, from, args) :: rs') &
        f args = r]
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
     | None => loc i = st :-> rs
    end.

Program Definition receive_loop' :
  {(rs : reqs)}, DHT [cl, W]
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
  (fun i => loc i = st :-> rs,
   fun (res : option nat) m => 
     exists (rs' : reqs) v from args ,
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
       [/\ res = Some v, loc m = st :-> rs',
        perm_eq rs ((cl, from, args) :: rs') &
        f args = res]) :=
  Do _ (@while cl W _ _ receive_loop_cond receive_loop_inv _
        (fun r => Do _ (
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
           r <-- tryrecv_resp;
           match r with
           | Some (_, _, msg) => ret _ _ (Some (head 0 msg))
           | None => ret _ _ None
           end)) None).

Next Obligation. by apply: with_spec x. Defined.
Next Obligation.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
by move:H; rewrite /receive_loop_inv (rely_loc' _ H0).
Qed.
Next Obligation.
apply:ghC=>i1 rs[];rewrite /receive_loop_cond.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
move/eqP=>->/=E1 C1; apply: step; apply: (gh_ex (g:=rs)).
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i2 (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
apply: call_rule=>//={r}res i2; case: res; last first.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
- move=>E2 C; apply:ret_rule=>i3 R2.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
  by rewrite /receive_loop_inv (rely_loc' _ R2).
case; case=>from v msg[rs'][E2]P F C2.
apply:ret_rule=>i3 R2; rewrite /receive_loop_inv (rely_loc' _ R2).
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
by exists rs', from, (behead msg).
Qed.

Next Obligation.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
apply: ghC=>i rs E1 C1; apply: (gh_ex (g:=rs)).
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (option (prod (prod nid nat) (list nat))) cl tryrecv_resp_act (@logvar (option perm) reqs (fun rs : reqs => @binarify (option perm) (fun i : state => @eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st rs)) (fun (r : option perm) (m : state) => match r as r' return (forall _ : @eq (option perm) r' r, Prop) with | Some p => let (p0, ms) as p0 return (forall _ : @eq (option perm) (@Some perm p0) r, Prop) := p in let (from, wildcard') as p1 return (forall _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) p1 ms)) r, Prop) := p0 in fun _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) (@pair nid nat from wildcard') ms)) r => @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat ms)) rs'))) (@eq (option nat) (f (@behead nat ms)) (@Some nat (@head nat O ms)))) | None => fun _ : @eq (option perm) (@None perm) r => @eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs) end (@Logic.eq_refl (option perm) r)))) *)
apply: call_rule=>//res m[].
rewrite /receive_loop_cond; case: res=>//=v _.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
move=>[rs'][from][args][E2]Hp F C2.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
by exists rs', v, from, args. 
Qed.

(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Blocking receive-loop that always returns a result (but may not
   terminate) *)
Program Definition blocking_receive_resp :
  {(rs : reqs)}, DHT [cl, W]
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
  (fun i => loc i = st :-> rs,
   fun (res :  nat) m => 
     exists (rs': reqs) from args ,
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
       [/\ loc m = st :-> rs',
        perm_eq rs ((cl, from, args) :: rs') &
        f args = Some res]) :=
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
  Do _ (r <-- receive_loop';
        match r with
        | Some res => ret _ _ res
        | None => ret _ _ 0
        end).
Next Obligation.
apply: ghC=>i rs E1 C1; apply: step; apply: (gh_ex (g:=rs)).
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (option (prod (prod nid nat) (list nat))) cl tryrecv_resp_act (@logvar (option perm) reqs (fun rs : reqs => @binarify (option perm) (fun i : state => @eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st rs)) (fun (r : option perm) (m : state) => match r as r' return (forall _ : @eq (option perm) r' r, Prop) with | Some p => let (p0, ms) as p0 return (forall _ : @eq (option perm) (@Some perm p0) r, Prop) := p in let (from, wildcard') as p1 return (forall _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) p1 ms)) r, Prop) := p0 in fun _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) (@pair nid nat from wildcard') ms)) r => @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat ms)) rs'))) (@eq (option nat) (f (@behead nat ms)) (@Some nat (@head nat O ms)))) | None => fun _ : @eq (option perm) (@None perm) r => @eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs) end (@Logic.eq_refl (option perm) r)))) *)
apply: call_rule=>//res i2[rs'][v][from][args][Z]E2 H1 H2.
subst res=>C2; apply: ret_rule=>i3 R2.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
by exists rs', from, args; rewrite (rely_loc' _ R2).
Qed.

(* Simple send_transition *)

Definition client_send_trans :=
  ProtocolWithInvariant.snd_transI (s2 l f prec cs cls).

Program Definition send_request server args :=
  act (@send_action_wrapper W cal cl l (prEq cal) client_send_trans _
                            args server).
Next Obligation. by rewrite InE; right; rewrite InE. Qed.


Program Definition compute_f (server : nid) (args: seq nat) : 
  DHT [cl, W]
  (fun i =>
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
     [/\ loc i = st :-> ([::] : reqs),
      prec args & server \in cs],
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
   fun (res : nat) m => loc m = st :-> ([::] : reqs) /\
                        f args = Some res) :=
  Do _ (send_request server args;;
        blocking_receive_resp).
Next Obligation.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
move=>i1/=[E1 H2 H3]. 
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
apply: step; apply: act_rule=>i2 R1.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (match zs as xs' return (forall _ : @eq (list input) xs' zs, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) zs => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') zs => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) zs)) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
case: (rely_coh R1)=>_ C2.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
have C': coh cal (getStatelet i2 l) by case: C2=>_ _ _ _/(_ l);rewrite prEq.
(* Goal: forall (rt : @receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l))) (pf : is_true (@in_mem nid cl (@mem nid (ssrbool.predPredType nid) (Protocols.Exports.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l) d)))) (coh_s : @Coherence.sort (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (getStatelet i2 l)) (_ : @InMem (@receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l))) rt (@Mem (@receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l))) (seq_PredType (@receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)))) (rcv_trans (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)))) (_ : @eq nat (tag tms) (@t_rcv (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt)) (_ : is_true (@msg_wf (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt d coh_s cl from tms)) (_ : network_rely (mkWorld (cal_with_inv l f prec cs cls)) cl (@UMC.upd Label dstatelet (union_mapUMC Label dstatelet) l (DStatelet (@UMC.upd nat_ordType Heap.heap (union_mapUMC nat_ordType Heap.heap) cl (@receive_step (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt cl from (tms_cont tms) d coh_s pf) (dstate d)) (consume_msg (dsoup d) mid)) i2) i4) (_ : @Coherence.sort (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) d) (_ : is_true (@eq_op nat_eqType (@t_rcv (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt) Exports.resp)), @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat (tms_cont tms))) rs'))) (@eq (option nat) (f (@behead nat (tms_cont tms))) (@Some nat (@head nat O (tms_cont tms))))) *)
split=>//=.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
- split=>//=.
(* Goal: @ex (PCM.sort (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage)))) (fun s' : PCM.sort (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage))) => @eq soup (dsoup d) (@PCM.join (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage))) (@um_pts State.mid (msg TaggedMessage) mid (@Msg TaggedMessage (TMsg resp tms) from cl true)) s')) *)
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
  + by split=>//; case: C'. 
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
  + rewrite/Actions.can_send -(cohD C2)/=domPt inE/= eqxx.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
    by rewrite mem_cat Hc orbC.
(* Goal: @ex (PCM.sort (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage)))) (fun s' : PCM.sort (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage))) => @eq soup (dsoup d) (@PCM.join (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage))) (@um_pts State.mid (msg TaggedMessage) mid (@Msg TaggedMessage (TMsg resp tms) from cl true)) s')) *)
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
  + rewrite/Actions.filter_hooks umfilt0=>???.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
    move => F.
    apply sym_eq in F.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
    move: F.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
    by move/find_some; rewrite dom0.
move=>y i3 i4[S]/=;case=>Z[b]/=[F]E3 R3; subst y.
(* Goal: match r as r' return (forall _ : @eq (option perm) r' r, Prop) with | Some p => let (p0, ms) as p0 return (forall _ : @eq (option perm) (@Some perm p0) r, Prop) := p in let (from, wildcard') as p1 return (forall _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) p1 ms)) r, Prop) := p0 in fun _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) (@pair nid nat from wildcard') ms)) r => @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat ms)) rs'))) (@eq (option nat) (f (@behead nat ms)) (@Some nat (@head nat O ms)))) | None => fun _ : @eq (option perm) (@None perm) r => @eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs) end (@Logic.eq_refl (option perm) r) *)
case: F=>/=F; subst b i3=>/=.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
rewrite -(rely_loc' _ R1) in E1.
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
rewrite (getStK _ E1) in R3.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (option (prod (prod nid nat) (list nat))) cl tryrecv_resp_act (@logvar (option perm) reqs (fun rs : reqs => @binarify (option perm) (fun i : state => @eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st rs)) (fun (r : option perm) (m : state) => match r as r' return (forall _ : @eq (option perm) r' r, Prop) with | Some p => let (p0, ms) as p0 return (forall _ : @eq (option perm) (@Some perm p0) r, Prop) := p in let (from, wildcard') as p1 return (forall _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) p1 ms)) r, Prop) := p0 in fun _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) (@pair nid nat from wildcard') ms)) r => @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat ms)) rs'))) (@eq (option nat) (f (@behead nat ms)) (@Some nat (@head nat O ms)))) | None => fun _ : @eq (option perm) (@None perm) r => @eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs) end (@Logic.eq_refl (option perm) r)))) *)
apply: (gh_ex (g:=[:: (cl, server, args)])).
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (option (prod (prod nid nat) (list nat))) cl tryrecv_resp_act (@logvar (option perm) reqs (fun rs : reqs => @binarify (option perm) (fun i : state => @eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st rs)) (fun (r : option perm) (m : state) => match r as r' return (forall _ : @eq (option perm) r' r, Prop) with | Some p => let (p0, ms) as p0 return (forall _ : @eq (option perm) (@Some perm p0) r, Prop) := p in let (from, wildcard') as p1 return (forall _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) p1 ms)) r, Prop) := p0 in fun _ : @eq (option perm) (@Some perm (@pair (prod nid nat) (list nat) (@pair nid nat from wildcard') ms)) r => @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat ms)) rs'))) (@eq (option nat) (f (@behead nat ms)) (@Some nat (@head nat O ms)))) | None => fun _ : @eq (option perm) (@None perm) r => @eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st rs) end (@Logic.eq_refl (option perm) r)))) *)
apply: call_rule=>//.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
- move=>C4; rewrite (rely_loc' _ R3) locE//; last by apply: (cohVl C').
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
  + by rewrite -(cohD C2) domPt inE/=.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
  by apply: (cohS C2).
(* Goal: forall (rt : @receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l))) (pf : is_true (@in_mem nid cl (@mem nid (ssrbool.predPredType nid) (Protocols.Exports.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l) d)))) (coh_s : @Coherence.sort (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (getStatelet i2 l)) (_ : @InMem (@receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l))) rt (@Mem (@receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l))) (seq_PredType (@receive_trans (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)))) (rcv_trans (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)))) (_ : @eq nat (tag tms) (@t_rcv (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt)) (_ : is_true (@msg_wf (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt d coh_s cl from tms)) (_ : network_rely (mkWorld (cal_with_inv l f prec cs cls)) cl (@UMC.upd Label dstatelet (union_mapUMC Label dstatelet) l (DStatelet (@UMC.upd nat_ordType Heap.heap (union_mapUMC nat_ordType Heap.heap) cl (@receive_step (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt cl from (tms_cont tms) d coh_s pf) (dstate d)) (consume_msg (dsoup d) mid)) i2) i4) (_ : @Coherence.sort (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) d) (_ : is_true (@eq_op nat_eqType (@t_rcv (Protocols.nodes (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) (Protocols.coh (getProtocol (mkWorld (cal_with_inv l f prec cs cls)) l)) rt) Exports.resp)), @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat (tms_cont tms))) rs'))) (@eq (option nat) (f (@behead nat (tms_cont tms))) (@Some nat (@head nat O (tms_cont tms))))) *)
clear R3=>v i5[rs'][from][args'][E5]P5 R C.  
(* Goal: @eq (list nat) tms (@cons nat (@head nat O tms) (@behead nat tms)) *)
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
suff X: args = args' /\ rs' = [::] by case: X=>Z X; subst args' rs'.  
(* Goal: @eq (list nat) tms (@cons nat (@head nat O tms) (@behead nat tms)) *)
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
suff X': rs' = [::].
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
- subst rs'; split=>//; move/perm_eq_mem: P5=>P5. 
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
  move/P5: (cl, server, args).
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
  by rewrite inE eqxx inE/==>/esym/eqP; case=>_->.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
by case/perm_eq_size: P5=>/esym/size0nil. 
Qed.

(**************************************************)
(*
Overall Implementation effort:

(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
5 person-hours

*)
(**************************************************)


(* More elaborated client program, compting a list of values *)

Definition compute_list_spec server ys :=
  forall (xs_acc : (seq input) * (seq (input * nat))),
  DHT [cl, W]
   (fun i =>
     let: (xs, acc) := xs_acc in         
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
     [/\ loc i = st :-> ([::] : reqs),
      all prec xs,
      all (fun e => f e.1 == Some e.2) acc,
(* Goal: @ex (PCM.sort (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage)))) (fun s' : PCM.sort (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage))) => @eq soup (dsoup d) (@PCM.join (@union_map_classPCM State.mid (msg TaggedMessage) (union_mapUMC State.mid (msg TaggedMessage))) (@um_pts State.mid (msg TaggedMessage) mid (@Msg TaggedMessage (TMsg resp tms) from cl true)) s')) *)
(* Goal: @ex reqs (fun rs' : reqs => and3 (@eq Heap.heap (getLocal cl (getStatelet i4 l)) (@heap_pts reqs st rs')) (is_true (@perm_eq (prod_eqType (prod_eqType nat_eqType nat_eqType) (seq_eqType nat_eqType)) rs (@cons (prod (prod nat nat) (list nat)) (@pair (prod nat nat) (list nat) (@pair nat nat cl from) (@behead nat tms)) rs'))) (@eq (option nat) (f (@behead nat tms)) (@Some nat (@head nat O tms)))) *)
      ys = map fst acc ++ xs &
      server \in cs],
   fun (res : seq (input * nat)) m =>
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
     [/\ loc m = st :-> ([::] : reqs),
      all (fun e => f e.1 == Some e.2) res &
      ys = map fst res]).

Program Definition compute_list_f server (xs : seq input) :
  DHT [cl, W]
   (fun i =>
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
     [/\ loc i = st :-> ([::] : reqs),
      all prec xs &
      server \in cs],
   fun (res : seq (input * nat)) m =>
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
     [/\ loc m = st :-> ([::] : reqs),
      all (fun e => f e.1 == Some e.2) res &
      xs = map fst res])
  :=
  Do (ffix (fun (rec : compute_list_spec server xs) xsa =>
    Do _ (let: (xs, acc) := xsa in         
          if xs is x :: xs' 
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
          then r <-- compute_f server x;
               let: acc' := rcons acc (x, r) in
               rec (xs', acc') 
          else ret _ _ acc)) (xs, [::])). 

Next Obligation.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (compute_list_f_obligation_1 (@pair (list input) (list (prod input nat)) l0 l4) (match l0 as xs' return (forall _ : @eq (list input) xs' l0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) l0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) l4 | cons x xs' => fun _ : @eq (list input) (@cons input x xs') l0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) l4 (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) l4 (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) l4 (@pair input nat x r))))) end (@Logic.eq_refl (list input) l0))) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec l0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) l4)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) l4) l0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
move=>i1/=[L1]; move:l0 l4=>zs acc H1 H2 H3 H4.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (match zs as xs' return (forall _ : @eq (list input) xs' zs, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) zs => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') zs => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) zs)) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
case: zs H1 H3=>//=[_|z zs/andP[H1]H5] H3. 
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
- by rewrite cats0 in H3;
  apply: ret_rule=>i2 R1; split=>//; rewrite ?(rely_loc' _ R1)//.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
apply: step; apply: call_rule=>//r i2[L2]F C2.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i2 (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
apply: call_rule=>//_; split=>//; first by rewrite all_rcons/= F eqxx.
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true true) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@Datatypes.nil input))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
(* Goal: @verify cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) i1 (@bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec z)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f z) (@Some nat res)))) (compute_f server z)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec zs)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat z r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat z r))) zs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) zs (@rcons (prod input nat) acc (@pair input nat z r)))))) (fun (y : list (prod input nat)) (m : state) => forall _ : and5 (@eq Heap.heap (getLocal cl (getStatelet i1 l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (andb (prec z) (@all (list nat) prec zs))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) (@cons input z zs))) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs))), and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) y)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) y))) *)
by rewrite map_rcons/= -cats1 -catA cat_cons/=.
Qed.

Next Obligation.
(* Goal: @conseq (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) cl (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true true) (@eq (list input) xs xs) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (@ffix cl (mkWorld (cal_with_inv l f prec cs cls)) (prod (list input) (list (prod input nat))) (fun _ : prod (list input) (list (prod input nat)) => list (prod input nat)) (fun x : prod (list input) (list (prod input nat)) => @binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := x in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (fun (rec : compute_list_spec server xs) (xsa : prod (list input) (list (prod input nat))) => @do' cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => let 'pair xs0 acc := xsa in and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs0)) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) acc)) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) acc) xs0)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (compute_list_f_obligation_1 xsa ((let 'pair xs0 acc as xsa' := xsa return (forall _ : @eq (prod (list input) (list (prod input nat))) xsa' xsa, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) in fun _ : @eq (prod (list input) (list (prod input nat))) (@pair (list input) (list (prod input nat)) xs0 acc) xsa => match xs0 as xs' return (forall _ : @eq (list input) xs' xs0, DT cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat))) with | Datatypes.nil => fun _ : @eq (list input) (@Datatypes.nil input) xs0 => @ret cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) acc | cons x xs' => fun _ : @eq (list input) (@cons input x xs') xs0 => @bind cl (mkWorld (cal_with_inv l f prec cs cls)) nat (list (prod input nat)) (@with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) nat (@binarify nat (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (prec x)) (is_true (@in_mem nid server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : nat) (m : state) => and (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (@eq (option nat) (f x) (@Some nat res)))) (compute_f server x)) (fun r : nat => @with_spec cl (mkWorld (cal_with_inv l f prec cs cls)) (list (prod input nat)) (@binarify (list (prod input nat)) (fun i : state => and5 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs')) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) (@rcons (prod input nat) acc (@pair input nat x r)))) (@eq (list input) xs (@cat input (@map (prod input nat) input (@fst input nat) (@rcons (prod input nat) acc (@pair input nat x r))) xs')) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) (rec (@pair (list input) (list (prod input nat)) xs' (@rcons (prod input nat) acc (@pair input nat x r))))) end (@Logic.eq_refl (list input) xs0)) (@Logic.eq_refl (prod (list input) (list (prod input nat))) xsa))) (compute_list_f_obligation_3 server xs rec xsa)) (@pair (list input) (list (prod input nat)) xs (@Datatypes.nil (prod input nat))))) (@binarify (list (prod input nat)) (fun i : state => and3 (@eq Heap.heap (getLocal cl (getStatelet i l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (list nat) prec xs)) (is_true (@in_mem nat server (@mem nat (seq_predType nat_eqType) cs)))) (fun (res : list (prod input nat)) (m : state) => and3 (@eq Heap.heap (getLocal cl (getStatelet m l)) (@heap_pts reqs st (@Datatypes.nil perm))) (is_true (@all (prod (list nat) nat) (fun e : prod (list nat) nat => @eq_op (option_eqType nat_eqType) (f (@fst (list nat) nat e)) (@Some nat (@snd (list nat) nat e))) res)) (@eq (list input) xs (@map (prod input nat) input (@fst input nat) res)))) *)
by move=>i1/=[L1]??; apply: call_rule=>//; rewrite cats0.
Qed.

End CalculatorRecieve.
