Library SP
Preamble: a lot of things just as in CC.
Section SPBase.
Variable Sig : Signature.
Notation Pid := (pid Sig).
Notation Var := (var Sig).
Notation Value := (value Sig).
Notation Expr := (expr Sig).
Notation BExpr := (bexpr Sig).
Notation RecVar := (recvar Sig).
Notation Ann := (ann Sig).
Notation Ev := (ev Sig).
Notation BEv := (bev Sig).
Notation Store := (State Pid Var Value).
Inductive Behaviour : Type :=
| End : Behaviour
| Send : Pid -> Expr -> Ann -> Behaviour -> Behaviour
| Recv : Pid -> Var -> Ann -> Behaviour -> Behaviour
| Sel : Pid -> Label -> Ann -> Behaviour -> Behaviour
| Branching : Pid -> option (Ann*Behaviour) -> option (Ann*Behaviour) -> Behaviour
| Cond : BExpr -> Behaviour -> Behaviour -> Behaviour
| Call : RecVar -> Behaviour
.
Induction principles on behaviours.
Fixpoint depth (B:Behaviour) : nat :=
match B with
| Send p e _ B' => 1 + depth B'
| Recv p x _ B' => 1 + depth B'
| Sel p l _ B' => 1 + depth B'
| Branching p mB mB' =>
1 + (match mB with None => 0 | Some (_,B) => depth B end)
+ (match mB' with None => 0 | Some (_,B) => depth B end)
| Cond b B1 B2 => 1 + Nat.max (depth B1) (depth B2)
| Call X => 1
| End => 1
end.
Theorem Behaviour_ind' :
forall P:Behaviour -> Prop,
P End ->
(forall p e a B, P B -> P (Send p e a B)) ->
(forall p v a B, P B -> P (Recv p v a B)) ->
(forall p l a B, P B -> P (Sel p l a B)) ->
(forall p, P (Branching p None None)) ->
(forall p a Bl, P Bl -> P (Branching p (Some (a,Bl)) None)) ->
(forall p a Br, P Br -> P (Branching p None (Some (a,Br)))) ->
(forall p a Bl a' Br, P Bl -> P Br ->
P (Branching p (Some (a,Bl)) (Some (a',Br)))) ->
(forall b B1 B2, P B1 -> P B2 -> P (Cond b B1 B2)) ->
(forall X, P (Call X)) ->
forall B, P B.
Theorem Behaviour_rec' :
forall P:Behaviour -> Type,
P End ->
(forall p e a B, P B -> P (Send p e a B)) ->
(forall p v a B, P B -> P (Recv p v a B)) ->
(forall p l a B, P B -> P (Sel p l a B)) ->
(forall p, P (Branching p None None)) ->
(forall p a Bl, P Bl -> P (Branching p (Some (a,Bl)) None)) ->
(forall p a Br, P Br -> P (Branching p None (Some (a,Br)))) ->
(forall p a Bl a' Br, P Bl -> P Br ->
P (Branching p (Some (a,Bl)) (Some (a',Br)))) ->
(forall b B1 B2, P B1 -> P B2 -> P (Cond b B1 B2)) ->
(forall X, P (Call X)) ->
forall B, P B.
Local Ltac dec_eq t t' H H' :=
case (eq_dec t t'); [intro H; rewrite <- H | right; intro; inversion H'; auto].
Equality of behaviours is decidable.
Lemma Behaviour_eq_dec : forall (B B':Behaviour), {B=B'} + {B<>B'}.
Lemma Behaviour_eq_End_dec : forall (b:Behaviour), {b=End} + {b<>End}.
A lot of definitions are parameterised on process lists, for decidability.
Definition within_ps (ps:list Pid) (N:Network) :=
forall p, ~In p ps -> N p = End.
Lemma within_ps_cons : forall ps N, within_ps ps N ->
forall p, within_ps (p::ps) N.
Lemma within_ps_rev : forall ps N, within_ps ps N ->
forall p, N p <> End -> In p ps.
Definition finite_support (N:Network) := exists ps, within_ps ps N.
Network equality is an equivalence relation, as expected.
Lemma Network_eq_refl : reflexive _ Network_eq.
Lemma Network_eq_sym : symmetric _ Network_eq.
Lemma Network_eq_trans : transitive _ Network_eq.
Lemma Network_eq_within_ps : forall ps N N',
within_ps ps N -> within_ps ps N' ->
(forall p, In p ps -> N p = N' p) -> Network_eq N N'.
Programs in SP are pairs, like choreography programs in CC.
Definition DefSetB := RecVar -> Behaviour.
Definition Program : Type := DefSetB * Network.
Definition Procs : Program -> DefSetB := fst.
Definition Net : Program -> Network := snd.
Lemma SP_eta : forall P, P = (Procs P,Net P).
Syntactic constructors for building networks as lists
Definition EmptyNet : Network := fun _ => End.
Definition Process (p:Pid) (B:Behaviour) : Network :=
fun p' => if (eq_dec p' p) then B else End.
Definition Par (N N':Network) :=
fun p => if (Behaviour_eq_End_dec (N p)) then N' p else N p.
Definition Network_rm (N:Network) (p:Pid) :=
fun r => if (eq_dec r p) then End else N r.
Definition Network_rm_ps (N:Network) (ps:list Pid) :=
fun r => if (in_dec (@eq_dec Pid) r ps) then End else N r.
Definition Network_res_ps (N:Network) (ps:list Pid) :=
fun r => if (in_dec (@eq_dec Pid) r ps) then N r else End.
End Syntax.
Add Parametric Relation : Network Network_eq
reflexivity proved by Network_eq_refl
symmetry proved by Network_eq_sym
transitivity proved by Network_eq_trans
as Network_eq_rel.
Pretty-printing rules. For some reason | only works if it is given an invalid level.
Delimit Scope SP_scope with SP.
Notation "p ! e @! a ; B" := (Send p e a B)
(at level 60, e at level 9, right associativity) : SP_scope.
Notation "p ? xx @? a ; B" := (Recv p xx a B)
(at level 60) : SP_scope.
Notation "p (+) l @+ a ; B" := (Sel p l a B)
(at level 60, l at level 9) : SP_scope.
Notation "p '&' B1 '//' B2" := (Branching p B1 B2)
(at level 60, no associativity) : SP_scope.
Notation "'If' e 'Then' B1 'Else' B2" := (Cond e B1 B2)
(at level 60) : SP_scope.
Notation "'bnil'" := (End) : SP_scope.
Notation "'nnil'" := (EmptyNet) : SP_scope.
Notation "N | N'" := (Par N N') (at level 201, right associativity) : SP_scope.
Notation "p [ B ]" := (Process p B) (at level 40, no associativity) : SP_scope.
Notation "N '\' p" := (Network_rm N p) (at level 40, no associativity) : SP_scope.
Notation "N (==) N'" := (Network_eq N N') (at level 80) : SP_scope.
Open Scope SP_scope.
A bunch of useful properties about networks.
Lemma EmptyNet_within_ps : forall ps, within_ps ps EmptyNet.
Lemma EmptyNet_finite_supp : finite_support EmptyNet.
Lemma Process_refl : forall p B, (p[B]) p = B.
Lemma Process_out : forall p B p', p <> p' -> (p[B]) p' = End.
Lemma Par_proj1 : forall N N' p, N p <> End -> (N | N') p = N p.
Lemma Par_proj2 : forall N N' p, N p = End -> (N | N') p = N' p.
Lemma Par_proj1' : forall N N' p, N' p = End -> (N | N') p = N p.
Lemma Par_assoc : forall N N' N'', (N | (N' | N'')) (==) ((N | N') | N'').
Useful results for networks with two processes.
Lemma Par_fst : forall p Bp q Bq, p <> q -> (p[Bp] | q[Bq]) p = Bp.
Lemma Par_snd : forall p Bp q Bq, p <> q -> (p[Bp] | q[Bq]) q = Bq.
Lemmas about subterms.
Lemma Send_neq_cont : forall p e a B, p ! e @! a; B <> B.
Lemma Recv_neq_cont : forall p x a B, p ? x @? a; B <> B.
Lemma Sel_neq_cont : forall p l a B, p (+) l @+ a; B <> B.
Lemma Branching_l_neq_cont : forall p a Bl Br, Branching p (Some (a,Bl)) Br <> Bl.
Lemma Branching_r_neq_cont : forall p a Bl Br, Branching p Bl (Some (a,Br)) <> Br.
Lemma Then_neq_cont : forall b B1 B2, If b Then B1 Else B2 <> B1.
Lemma Else_neq_cont : forall b B1 B2, If b Then B1 Else B2 <> B2.
If two networks do not share any running processes, then their parallel composition is symmetric.
Definition Network_disjoint (N N':Network) :=
forall p, N p = End \/ N' p = End.
Lemma Network_disjoint_sym : forall N N',
Network_disjoint N N' -> Network_disjoint N' N.
Lemma Par_comm : forall N N', Network_disjoint N N' -> (N | N') (==) (N' | N).
Lemma Par_eq : forall N1 N2 N1' N2',
N1 (==) N1' -> N2 (==) N2' -> (N1 | N2) (==) (N1' | N2').
Properties of removal.
Lemma Network_rm_In : forall N p, (N \ p) p = End.
Lemma Network_rm_out : forall N p p', p <> p' -> (N \ p) p' = N p'.
Lemma Network_rm_add : forall N p, N (==) (N \ p | p[N p]).
Lemma Network_rm_within_ps : forall N p ps,
within_ps (p::ps) N -> within_ps ps (N \ p).
Lemma Network_rm_add_2_p : forall N p q Bp Bq, p <> q ->
(N \ p \ q | p[Bp] | q[Bq]) p = Bp.
Lemma Network_rm_add_2_q : forall N p q Bp Bq, p <> q ->
(N \ p \ q | p[Bp] | q[Bq]) q = Bq.
Lemma Network_rm_add_2_out : forall N p q r Bp Bq,
p <> r -> q <> r -> (N \ p \ q | p[Bp] | q[Bq]) r = N r.
Lemma Network_rm_eq : forall N N', N (==) N' -> forall p, N \ p (==) N' \ p.
Lemma Network_rm_res_ps :
forall N ps, N (==) (Network_rm_ps N ps | Network_res_ps N ps).
Rewriting of networks.
Lemma Network_eq_cross'' : forall N N1 N2 p q Bp Bq,
p <> q -> N1 (==) (N \ p | p[Bp]) -> N2 (==) (N \ q | q[Bq]) ->
(N2 \ p | p[Bp]) (==) (N1 \ q | q[Bq]).
For a simpler formulation of the next lemmas.
Definition disj_3 (p q r:Pid) := p <> q /\ p <> r /\ q <> r.
Definition disj_4 (p q r s:Pid) :=
p <> q /\ p <> r /\ p <> s /\ q <> r /\ q <> s /\ r <> s.
Local Ltac elim_3 H Hpq Hpr Hqr := destruct H as [Hpq [Hpr Hqr] ].
Local Ltac elim_4 H Hpq Hpr Hps Hqr Hqs Hrs :=
destruct H as [Hpq [Hpr [Hps [Hqr [Hqs Hrs] ] ] ] ].
Lemma Network_eq_cross' : forall N N1 N2 p q r Bp Bq Br, disj_3 p q r ->
N1 (==) (N \ p \ q | p[Bp] | q[Bq]) -> N2 (==) (N \ r | r[Br]) ->
(N2 \ p \ q | p[Bp] | q[Bq]) (==) (N1 \ r | r[Br]).
Lemma Network_eq_cross : forall N N1 N2 p q r s Bp Bq Br Bs, disj_4 p q r s ->
N1 (==) (N \ p \ q | p[Bp] | q[Bq]) -> N2 (==) (N \ r \ s | r[Br] | s[Bs]) ->
(N2 \ p \ q | p[Bp] | q[Bq]) (==) (N1 \ r \ s | r[Br] | s[Bs]).
Lemma Network_eq_within_ps_dec : forall ps N N',
within_ps ps N -> within_ps ps N' -> { N (==) N' }+{~ (N (==) N') }.
Fixpoint Behaviour_WF (p:Pid) (B:Behaviour) : Prop :=
match B with
| q ! _ @! _ ; B' => p <> q /\ Behaviour_WF p B'
| q ? _ @? _ ; B' => p <> q /\ Behaviour_WF p B'
| q (+) l @+ _; B' => p <> q /\ Behaviour_WF p B'
| q & B1 // B2 => p <> q
/\ (match B1 with None => True | Some (_,B) => Behaviour_WF p B end)
/\ (match B2 with None => True | Some (_,B) => Behaviour_WF p B end)
| (If e Then B1 Else B2) => Behaviour_WF p B1 /\ Behaviour_WF p B2
| Call _ => True
| End => True
end.
Lemma Behaviour_WF_dec : forall p B, {Behaviour_WF p B} + {~Behaviour_WF p B}.
Definition Network_WF (N:Network) : Prop := forall p, Behaviour_WF p (N p).
Lemma Network_WF_dec : forall ps N, within_ps ps N ->
{Network_WF N} + {~Network_WF N}.
Lemma Par_WF : forall N N', Network_WF N -> Network_WF N' -> Network_WF (N | N').
Lemma WF_Par1 : forall N N', Network_WF (N | N') -> Network_WF N.
Lemma WF_Par2 : forall N N', Network_disjoint N N' ->
Network_WF (N | N') -> Network_WF N'.
Lemma Network_WF_par : forall N N', Network_disjoint N N' ->
Network_WF (N | N') -> Network_WF N /\ Network_WF N'.
Lemma Network_WF_comm : forall N N', Network_disjoint N N' ->
Network_WF (N | N') -> Network_WF (N' | N).
Program_WF doesn't make sense, because procedures don't know the processes
that will execute them, so we do not know what to pass to Behaviour_WF.
But: program with WF network reduces to program with WF network is
an interesting property that is guaranteed by EPP.
Same strategy as for CC.
Inductive SP_To (D : DefSetB) :
Network -> Store -> (RichLabel Pid Value Var RecVar) -> Network -> Store -> Prop :=
| S_Com N p e a B q x a' B' N' s s' :
N p = (q ! e @!a ; B) -> N q = (p ? x @? a'; B') ->
let v := (eval_on_state Ev e s p) in
N' (==) (N \ p \ q | p[B] | q[B']) -> s' [==] (s[[q,x => v]]) ->
SP_To D N s (RL_Com p v q x) N' s'
| S_LSel N p a B q a' Bl Br N' s s' :
N p = (q (+) left @+ a ; B) -> N q = (p & Some (a',Bl) // Br) ->
N' (==) (N \ p \ q | p[B] | q[Bl]) -> s [==] s' ->
SP_To D N s (RL_Sel p q left) N' s'
| S_RSel N p a B q a' Bl Br N' s s' :
N p = (q (+) right @+ a ; B) -> N q = (p & Bl // Some (a',Br)) ->
N' (==) (N \ p \ q | p[B] | q[Br]) -> s [==] s' ->
SP_To D N s (RL_Sel p q right) N' s'
| S_Then N p b B1 B2 N' s s' :
N p = (If b Then B1 Else B2) ->
eval_on_state BEv b s p = true ->
N' (==) (N \ p | p[B1]) -> s [==] s' ->
SP_To D N s (RL_Cond p) N' s'
| S_Else N p b B1 B2 N' s s' :
N p = (If b Then B1 Else B2) ->
eval_on_state BEv b s p = false ->
N' (==) (N \ p | p[B2]) -> s [==] s' ->
SP_To D N s (RL_Cond p) N' s'
| S_Call N p X N' s s' :
N p = Call X ->
N' (==) (N \ p | p[D X]) -> s [==] s' ->
SP_To D N s (RL_Call X p) N' s'.
Notation "<< N , s >> --[ tl , D ]--> << N' , s' >>" :=
(SP_To D N s tl N' s') (at level 100) : SP_scope.
Default reductions.
Lemma S_Com' : forall D N p e a B q x a' B' s,
N p = (q ! e @! a ; B) -> N q = (p ? x @? a' ; B') ->
let v := (eval_on_state Ev e s p) in
<<N,s>> --[RL_Com p v q x,D]--> <<N \ p \ q | p[B] | q[B'],s[[q,x => v]]>>.
Lemma S_LSel' : forall D N p a B q a' Bl Br s,
N p = (q (+) left @+ a ; B) -> N q = (p & Some (a',Bl) // Br) ->
<<N,s>> --[RL_Sel p q left,D]--> <<N \ p \ q | p[B] | q[Bl],s>>.
Lemma S_RSel' : forall D N p a B q a' Bl Br s,
N p = (q (+) right @+ a ; B) -> N q = (p & Bl // Some (a',Br)) ->
<<N,s>> --[RL_Sel p q right,D]--> <<N \ p \ q | p[B] | q[Br], s>>.
Lemma S_Then' : forall D N p b B1 B2 s,
N p = (If b Then B1 Else B2) -> eval_on_state BEv b s p = true ->
<<N,s>> --[RL_Cond p,D]--> <<N \ p | p[B1],s>>.
Lemma S_Else' : forall D N p b B1 B2 s,
N p = (If b Then B1 Else B2) -> eval_on_state BEv b s p = false ->
<<N,s>> --[RL_Cond p,D]--> <<N \ p | p[B2],s>>.
Lemma S_Call' : forall D N p X s, N p = Call X ->
<<N,s>> --[RL_Call X p,D]--> <<N \ p | p[D X],s>>.
Definition Configuration : Type := Program * Store.
Inductive SPP_To :
Configuration -> (TransitionLabel Pid Value) -> Configuration -> Prop :=
| SPP_Base D N s t N' s' : SP_To D N s t N' s' ->
SPP_To (D,N,s) (forget t) (D,N',s').
Inductive SPP_ToStar :
Configuration -> list (TransitionLabel Pid Value) -> Configuration -> Prop :=
| SPT_Base P s s' : s [==] s' -> SPP_ToStar (P,s) nil (P,s')
| SPT_Step c1 t c2 l c3 : SPP_To c1 t c2 ->
SPP_ToStar c2 l c3 -> SPP_ToStar c1 (t::l) c3
.
Lemma SPT_Refl : forall c, SPP_ToStar c nil c.
End Semantics.
Notation "<< N , s >> --[ tl , D ]--> << N' , s' >>" :=
(SP_To D N s tl N' s') (at level 100) : SP_scope.
Notation "C --[ l ]--> C'" := (SPP_To C l C')
(at level 50, left associativity) : SP_scope.
Notation "C --[ ls ]-->* C'" := (SPP_ToStar C ls C')
(at level 50, left associativity) : SP_scope.
Reductions are preserved by state equivalence...
Lemma SP_To_eq : forall D N tl s1 N' s2 s1' s2', s1 [==] s1' -> s2 [==] s2' ->
<<N,s1>> --[tl,D]--> <<N',s2>> -> <<N,s1'>> --[tl,D]--> <<N',s2'>>.
Lemma SPP_To_eq : forall P s1 tl P' s2 s1' s2', s1 [==] s1' -> s2 [==] s2' ->
(P,s1) --[tl]--> (P',s2) -> (P,s1') --[tl]--> (P',s2').
Lemma SPP_ToStar_eq : forall P s1 tl P' s2 s1' s2',
s1 [==] s1' -> s2 [==] s2' ->
(P,s1) --[tl]-->* (P',s2) -> (P,s1') --[tl]-->* (P',s2').
...by network equivalence...
Lemma SP_To_Network_eq : forall N1 N' N2 D s s' tl, (N1 (==) N2) ->
<<N1,s>> --[tl,D]--> <<N',s'>> -> <<N2,s>> --[tl,D]--> <<N',s'>>.
Lemma SPP_To_Network_eq : forall P1 P1' P2 s s' tl,
(Net P1 (==) Net P1') -> (Procs P1 = Procs P1') ->
(P1,s) --[tl]--> (P2,s') -> (P1',s) --[tl]--> (P2,s').
Lemma SPP_ToStar_Network_eq : forall P1 P1' P2 s s' tl,
(Net P1 (==) Net P1') -> (Procs P1 = Procs P1') -> tl <> nil ->
(P1,s) --[tl]-->* (P2,s') -> (P1',s) --[tl]-->* (P2,s').
... and by extensionally equal sets of procedure definitions.
Lemma SP_To_Defs_wd : forall D D', (forall X, D X = D' X) ->
forall N s tl N' s',
<<N,s>> --[tl,D]--> <<N',s'>> -> <<N,s>> --[tl,D']--> <<N',s'>>.
The set of procedure definitions never changes.
Hypothesis D : DefSetB.
Lemma SPP_To_Defs_stable : forall D' N N' tl s s',
(D,N,s) --[tl]--> (D',N',s') -> D = D'.
Lemma SPP_ToStar_Defs_stable : forall D' N N' tl s s',
(D,N,s) --[tl]-->* (D',N',s') -> D = D'.
Reductions and state.
Lemma SP_To_disjoint_eval : forall N s tl s' p e N',
disjoint_p_rl p tl -> <<N,s>> --[tl,D]--> <<N',s'>> ->
eval_on_state Ev e s p = eval_on_state Ev e s' p.
Lemma SP_To_disjoint_beval : forall N s tl s' p b N',
disjoint_p_rl p tl -> <<N,s>> --[tl,D]--> <<N',s'>> ->
eval_on_state BEv b s p = eval_on_state BEv b s' p.
Lemma SP_To_disjoint_update : forall N s tl s' p x v N',
disjoint_p_rl p tl -> <<N,s>> --[tl,D]--> <<N',s'>> ->
<<N,s[[p,x => v]]>> --[tl,D]--> <<N',s'[[p,x => v]]>>.
Determinism of reductions given the label.
Lemma SP_To_deterministic_1 : forall N N1 N2 tl s s1 s2,
<<N,s>> --[tl,D]--> <<N1,s1>> -> <<N,s>> --[tl,D]--> <<N2,s2>> -> N1 (==) N2.
Lemma SP_To_deterministic_2 : forall N N1 N2 tl s s1 s2,
<<N,s>> --[tl,D]--> <<N1,s1>> -> <<N,s>> --[tl,D]--> <<N2,s2>> -> s1 [==] s2.
Lemma SP_To_deterministic : forall N N1 N2 tl1 tl2 s s1 s2,
<<N,s>> --[tl1,D]--> <<N1,s1>> -> <<N,s>> --[tl2,D]--> <<N2,s2>> ->
tl1 = tl2 -> (N1 (==) N2) /\ s1 [==] s2.
Ltac diff_assert p q H1 H2 H3 := assert (p <> q) as H1;
[intro H1; rewrite H1, H2 in H3; inversion H3 | idtac].
Lemma SP_To_deterministic_4 : forall N N' tl1 tl2 s s1 s2,
<<N,s>> --[tl1,D]--> <<N',s1>> -> <<N,s>> --[tl2,D]--> <<N',s2>> ->
s1 [==] s2.
The label alone determines the resulting state.
Lemma SP_To_rl_implies_state : forall N1 s tl N1' s1 N2 N2' s2,
<<N1,s>> --[tl,D]--> <<N1',s1>> -> <<N2,s>> --[tl,D]--> <<N2',s2>> ->
s1 [==] s2.
Lemma diamond_SP : forall N s tl1 tl2 N1 N2 s1 s2,
<<N,s>> --[tl1,D]--> <<N1,s1>> -> <<N,s>> --[tl2,D]--> <<N2,s2>> ->
tl1 <> tl2 -> exists N' s',
<<N1,s1>> --[tl2,D]--> <<N',s'>> /\ <<N2,s2>> --[tl1,D]--> <<N',s'>>.
End Determinism.
Useful generalizations
Lemma SPP_To_deterministic_1 : forall P s tl P' s' P'' s'',
(P,s) --[tl]--> (P',s') -> (P,s) --[tl]--> (P'',s'') ->
Net P' (==) Net P''.
Lemma SPP_To_deterministic_2 : forall P s tl P' s' P'' s'',
(P,s) --[tl]--> (P',s') -> (P,s) --[tl]--> (P'',s'') -> s' [==] s''.
Lemma SPP_To_deterministic : forall P s tl P' s' P'' s'',
(P,s) --[tl]--> (P',s') -> (P,s) --[tl]--> (P'',s'') ->
(Net P' (==) Net P'') /\ Procs P' = Procs P'' /\ s' [==] s''.
Lemma SPP_ToStar_deterministic_1 : forall P s tl P' s' P'' s'',
(P,s) --[tl]-->* (P',s') -> (P,s) --[tl]-->* (P'',s'')
-> Net P' (==) Net P''.
End SPBase.
Delimit Scope SP_scope with SP.
Notation "p ! e @! a ; B" := (Send _ p e a B)
(at level 60, e at level 9, right associativity) : SP_scope.
Notation "p ? xx @? a ; B" := (Recv _ p xx a B)
(at level 60, right associativity) : SP_scope.
Notation "p (+) l @+ a ; B" := (Sel _ p l a B)
(at level 49, l at level 9, right associativity) : SP_scope.
Notation "p '&' B1 '//' B2" := (Branching _ p B1 B2)
(at level 60, no associativity) : SP_scope.
Notation "'If' e 'Then' B1 'Else' B2" := (Cond _ e B1 B2)
(at level 60) : SP_scope.
Notation "'bnil'" := (End _) : SP_scope.
Notation "'nnil'" := (EmptyNet _) : SP_scope.
Notation "<< N , s >> --[ tl , D ]--> << N' , s' >>" :=
(SP_To _ D N s tl N' s') (at level 100) : SP_scope.
Notation "C --[ l ]--> C'" := (SPP_To _ C l C')
(at level 50, left associativity) : SP_scope.
Notation "C --[ ls ]-->* C'" := (SPP_ToStar _ C ls C')
(at level 50, left associativity) : SP_scope.
Notation "N | N'" := (Par _ N N') (at level 202, right associativity) : SP_scope.
Notation "p [ B ]" := (Process _ p B) (at level 201, no associativity) : SP_scope.
Notation "N \ p" := (Network_rm _ N p) (at level 50, no associativity) : SP_scope.
Notation "N (==) N'" := (Network_eq _ N N') (at level 80) : SP_scope.
Tactics for proofs by induction.
Ltac BInduction B := induction B using Behaviour_ind'.
Ltac BDInduction B B' := induction B using Behaviour_ind'; induction B' using Behaviour_ind'.
Ltac elim_as mB p := case mB; try induction p.
Ltac opt_elim b p := case_eq b; repeat induction p.
Tactics for network equality.
Ltac NEQr := apply Network_eq_refl.
Ltac NEQs := apply Network_eq_sym; auto.
Ltac NEQt N := apply Network_eq_trans with N; auto.