File: Indist.v

package info (click to toggle)
coq-quickchick 2.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,432 kB
  • sloc: ml: 4,367; ansic: 789; makefile: 388; sh: 27; python: 4; lisp: 2; perl: 2
file content (126 lines) | stat: -rw-r--r-- 3,317 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
From QuickChick Require Import QuickChick.
Require Import ZArith.
Require Import List.

From QuickChick.ifcbasic Require Import Machine.

(* Manual, handwritten indist instances *)

Fixpoint forallb2 {A : Type} (f : A -> A -> bool) (l1 l2 :list A) : bool :=
  match l1, l2 with
    | nil, nil => true
    | cons h1 t1, cons h2 t2 => f h1 h2 && forallb2 f t1 t2
    | _, _ => false
  end.

(* Indistinguishability type class *)
Class Indist (A : Type) : Type :=
{
  indist : A -> A -> bool
}.

#[global]
Instance indist_atom : Indist Atom :=
{|
  indist a1 a2 :=
    let '(x1@l1) := a1 in
    let '(x2@l2) := a2 in
    match l1, l2 with
      | L, L => Z.eqb x1 x2
      | H, H => true
      | _, _ => false
    end
|}.

#[global]
Instance indist_mem : Indist Mem :=
{|
  indist m1 m2 := forallb2 indist m1 m2
|}.

Fixpoint cropTop (s:Stack) : Stack :=
  match s with
    | Mty        => Mty
    | x::s'      => cropTop s'
    | (x@H:::s') => cropTop s'
    | (_@L:::_)  => s
  end.

(* Assumes stacks have been cropTopped! *)
#[global]
Instance indist_stack : Indist Stack :=
{|
  indist s1 s2 :=
    let fix aux s1 s2 :=
        match s1, s2 with
          | a1::s1', a2::s2' => indist a1 a2 && aux s1' s2'
          | a1:::s1', a2:::s2' => indist a1 a2 && aux s1' s2'
          | Mty, Mty => true
          | _, _ => false
        end
    in aux s1 s2
|}.

#[global]
Instance indist_state : Indist State :=
{|
  indist st1 st2 :=
    let '(St imem1 mem1 stk1 pc1) := st1 in
    let '(St imem2 mem2 stk2 pc2) := st2 in
    if negb (indist mem1 mem2) then (* trace "Memory" *) false
    else if negb (indist pc1 pc2) then (* trace "PC" *) false
    else let (stk1',stk2') :=
           match pc1 with
             | _ @ H => (cropTop stk1, cropTop stk2)
             | _ => (stk1, stk2)
           end in
    if negb (indist stk1' stk2') then (* trace "Stack" *) false
    else true
|}.

(* Inductive versions *)

Inductive IndistAtom : Atom -> Atom -> Prop :=
| IAtom_Lo : forall x, IndistAtom (x@L) (x@L)
| IAtom_Hi : forall x y, IndistAtom (x@H) (y@H).

Derive DecOpt for (IndistAtom a1 a2).

Inductive IndistMem : Mem -> Mem -> Prop :=
| IMem_Nil  : IndistMem nil nil
| IMem_Cons : forall a1 a2 m1 m2,
    IndistAtom a1 a2 -> IndistMem  m1 m2 ->
    IndistMem (cons a1 m1) (cons a2 m2).

Derive DecOpt for (IndistMem m1 m2).

Inductive IndistStack : Stack -> Stack -> Prop :=
| IStack_Mty  : IndistStack Mty Mty
| IStack_Cons : forall a1 a2 s1 s2,
    IndistAtom a1 a2 -> IndistStack s1 s2 ->
    IndistStack (Cons a1 s1) (Cons a2 s2)
| IStack_RetCons : forall a1 a2 s1 s2,
    IndistAtom a1 a2 -> IndistStack s1 s2 ->
    IndistStack (RetCons a1 s1) (RetCons a2 s2).

Derive DecOpt for (IndistStack s1 s2).

#[global] Instance Label_DecEq (l1 l2 : Label) : Dec (l1 = l2).
Proof. dec_eq. Defined.

Inductive IndistState : State -> State -> Prop :=
| IState_Low : forall im1 im2 m1 m2 s1 s2 pc1 pc2,
    IndistAtom pc1 pc2 ->
    IndistMem m1 m2 ->
    pc_lab pc1 = L ->
    IndistStack s1 s2 ->
    IndistState (St im1 m1 s1 pc1) (St im2 m2 s2 pc2)
| IState_High : forall im1 im2 m1 m2 s1 s2 pc1 pc2,
    IndistAtom pc1 pc2 ->
    IndistMem m1 m2 ->
    pc_lab pc1 = H ->
    IndistStack (cropTop s1) (cropTop s2) ->
    IndistState (St im1 m1 s1 pc1) (St im2 m2 s2 pc2).

Derive DecOpt for (IndistState s1 s2).