Expressions.v 6.83 KB
Newer Older
1
2
3
(**
Formalization of the base expression language for the daisy framework
 **)
4
Require Import Coq.Reals.Reals.
Heiko Becker's avatar
Heiko Becker committed
5
Require Import Daisy.Infra.RealConstruction.
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Set Implicit Arguments.
(**
  Expressions will use binary operators.
  Define them first
**)
Inductive binop : Type := Plus | Sub | Mult | Div.
(**
  Next define an evaluation function for binary operators on reals.
  Errors are added on the expression evaluation level later.
 **)
Fixpoint eval_binop (o:binop) (v1:R) (v2:R) :=
  match o with
  | Plus => Rplus v1 v2
  | Sub => Rminus v1 v2
  | Mult => Rmult v1 v2
  | Div => Rdiv v1 v2
  end.
23
(**
24
25
  Define expressions parametric over some value type V.
  Will ease reasoning about different instantiations later.
26
27
28
29
  Note that we differentiate between wether we use a variable from the environment or a parameter.
  Parameters do not have error bounds in the invariants, so they must be perturbed, but variables from the
  program will be perturbed upon binding, so we do not need to perturb them.
**)
30
31
Inductive exp (V:Type): Type :=
  Var: nat -> exp V
32
| Param: nat -> exp V
33
34
35
36
| Const: V -> exp V
| Binop: binop -> exp V -> exp V -> exp V.
(**
  Define the machine epsilon for floating point operations.
37
  Current value: 2^(-53)
Heiko Becker's avatar
Heiko Becker committed
38
39
 **)
Definition machineEpsilon:R := realFromNum 1 1 53.
40
41
42
43
44
(**
  Define a perturbation function to ease writing of basic definitions
**)
Definition perturb (r:R) (e:R) :=
  Rmult r (Rplus 1 e).
45
46
47
48
(**
  Abbreviation for the type of an environment
 **)
Definition env_ty := nat -> R.
49
(**
50
51
  Define expression evaluation relation parametric by an "error" delta.
  This value will be used later to express float computations using a perturbation
52
53
  of the real valued computation by (1 + d)
**)
54
Inductive eval_exp (eps:R) (env:env_ty) : (exp R) -> R -> Prop :=
55
  Var_load x: eval_exp eps env (Var R x) (env x)
56
| Param_acc x delta: ((Rabs delta) <= eps)%R -> eval_exp eps env (Param R x) (perturb (env x) delta)
57
58
59
60
61
62
63
64
| Const_dist n delta:
    Rle (Rabs delta) eps ->
    eval_exp eps env (Const n) (perturb n delta)
|Binop_dist op e1 e2 v1 v2 delta:
   Rle (Rabs delta) eps ->
                eval_exp eps env e1 v1 ->
                eval_exp eps env e2 v2 ->
                eval_exp eps env (Binop op e1 e2) (perturb (eval_binop op v1 v2) delta).
65
66
(**
  Define real evaluation as stated above:
67
 **)
68
Definition is_real_value (e:exp R) (env:env_ty) (v:R) := eval_exp R0 env e v.
69
(**
70
71
72
73
74
75
76
77
78
79
80
81
82
83
  Prove that using eps = 0 makes the evaluation deterministic
 **)
Lemma Rabs_0_impl_eq (d:R):
  Rle (Rabs d) R0 -> d = R0.
Proof.
  intros abs_leq_0.
  pose proof (Rabs_pos d) as abs_geq_0.
  pose proof (Rle_antisym (Rabs d) R0 abs_leq_0 abs_geq_0) as Rabs_eq.
  rewrite <- Rabs_R0 in Rabs_eq.
  apply Rsqr_eq_asb_1 in Rabs_eq.
  rewrite Rsqr_0 in Rabs_eq.
  apply Rsqr_0_uniq in Rabs_eq; assumption.
Qed.

Heiko Becker's avatar
Heiko Becker committed
84
85
86
87
88
89
90
91
92
93
94
95
Lemma perturb_0_val (v:R) (delta:R):
  (Rabs delta <= 0)%R ->
  perturb v delta = v.
Proof.
  intros abs_0; apply Rabs_0_impl_eq in abs_0; subst.
  unfold perturb.
  rewrite Rmult_plus_distr_l.
  rewrite Rmult_0_r.
  rewrite Rmult_1_r.
  rewrite Rplus_0_r; auto.
Qed.

96
97
98
99
100
101
102
103
104
105
106
107
108
109
Lemma eval_det (e:exp R) (env:env_ty):
  forall v1 v2,
  eval_exp R0 env e v1 ->
  eval_exp R0 env e v2 ->
  v1 = v2.
Proof.
  induction e; intros v1 v2 eval_v1 eval_v2;
    inversion eval_v1; inversion eval_v2; [ auto | | | ];
      repeat try rewrite perturb_0_val; auto.
  subst.
  rewrite (IHe1 v0 v4); auto.
  rewrite (IHe2 v3 v5); auto.
Qed.

Heiko Becker's avatar
Heiko Becker committed
110
111
112
113
114
115
Lemma Rsub_eq_Ropp_Rplus (a:R) (b:R) :
  (a - b = a + (- b))%R.
Proof.
  field_simplify; reflexivity.
Qed.

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
Lemma Rabs_err_simpl:
  forall a b,
    (Rabs (a - (a * (1 + b))) = Rabs (a * b))%R.
Proof.
  intros a b.
  rewrite Rmult_plus_distr_l.
  rewrite Rmult_1_r.
  rewrite Rsub_eq_Ropp_Rplus.
  rewrite Ropp_plus_distr.
  assert (- a + (- (a * b)) = ( - (a * b) + - a))%R by (rewrite Rplus_comm; auto).
  rewrite H.
  rewrite <- Rsub_eq_Ropp_Rplus.
  rewrite Rplus_minus.
  rewrite Rabs_Ropp; reflexivity.
Qed.

132
133
134
(**
  TODO: Check wether we need Rabs (n * machineEpsilon) instead
**)
Heiko Becker's avatar
Heiko Becker committed
135
136
137
138
Lemma const_abs_err_bounded (n:R) (nR:R) (nF:R):
  forall cenv:nat -> R,
  eval_exp 0%R cenv (Const n) nR ->
  eval_exp machineEpsilon cenv (Const n) nF ->
139
  (Rabs (nR - nF) <= Rabs n * machineEpsilon)%R.
Heiko Becker's avatar
Heiko Becker committed
140
141
142
143
144
145
Proof.
  intros cenv eval_real eval_float.
  inversion eval_real; subst.
  rewrite perturb_0_val; auto.
  inversion eval_float; subst.
  unfold perturb; simpl.
146
  rewrite Rabs_err_simpl.
Heiko Becker's avatar
Heiko Becker committed
147
  repeat rewrite Rabs_mult.
148
  apply Rmult_le_compat_l; [apply Rabs_pos | auto].
Heiko Becker's avatar
Heiko Becker committed
149
150
Qed.

151
152
153
154
(**
  TODO: Maybe improve bound by adding interval constraint and proving that it is leq than maxAbs of bounds
  (nlo <= cenv n <= nhi)%R ->   (Rabs (nR - nF) <= Rabs ((Rmax (Rabs nlo) (Rabs nhi)) * machineEpsilon))%R.
**)
155
Lemma param_abs_err_bounded (n:nat) (nR:R) (nF:R) (cenv:nat->R):
156
157
158
  eval_exp 0%R cenv (Param R n) nR ->
  eval_exp machineEpsilon cenv (Param R n) nF ->
  (Rabs (nR - nF) <= Rabs (cenv n) * machineEpsilon)%R.
Heiko Becker's avatar
Heiko Becker committed
159
Proof.
160
  intros eval_real eval_float.
Heiko Becker's avatar
Heiko Becker committed
161
  inversion eval_real; subst.
162
163
164
  rewrite perturb_0_val; auto.
  inversion eval_float; subst.
  unfold perturb; simpl.
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  rewrite Rabs_err_simpl.
  repeat rewrite Rabs_mult.
  apply Rmult_le_compat_l; [ apply Rabs_pos | auto].
Qed.

(*

Lemma add_abs_err_bounded (e1:exp R) (e1R:R) (e1F:R) (e2:exp R) (e2R:R) (e2F:R) (vR:R) (vF:R) (cenv:nat->R) (err1:R) (err2:R):
  eval_exp 0%R cenv e1 e1R ->
  eval_exp machineEpsilon cenv e1 e1F ->
  eval_exp 0%R cenv e2 e2R ->
  eval_exp machineEpsilon cenv e2 e2F ->
  eval_exp 0%R cenv (Binop Plus e1 e2) vR ->
  eval_exp machineEpsilon cenv (Binop Plus e1 e2) vF ->
  (Rabs (e1R - e1F) <= err1)%R ->
  (Rabs (e2R - e2F) <= err2)%R ->
  (Rabs (vR - vF) <= err1 + err2 + Rabs vR * machineEpsilon)%R.
Proof.
  intros e1_real e1_float e2_real e2_float plus_real plus_float bound_e1 bound_e2.
  inversion plus_real; subst.
  rewrite perturb_0_val; auto.
  inversion plus_float; subst.
  unfold perturb; simpl.
188
189
190
191
  rewrite Rmult_plus_distr_l.
  rewrite Rmult_1_r.
  rewrite Rsub_eq_Ropp_Rplus.
  rewrite Ropp_plus_distr.
192
193
194
195
  rewrite (eval_det e1_real H4) in e1_real.
  rewrite (eval_det e2_real H5) in e2_real.
  pose proof (Rabs_triang (v1 + v2) (- (v0 + v3) + - ((v0 + v3) * delta0))).
 *)
Heiko Becker's avatar
Heiko Becker committed
196

197
198
199
200
201
202
203
204
(**
  Using the parametric expressions, define boolean expressions for conditionals
**)
Inductive bexp (V:Type) : Type :=
  leq: exp V -> exp V -> bexp V
| less: exp V -> exp V -> bexp V.
(**
  Define evaluation of booleans for reals
205
 **)
206
Inductive bval (eps:R) (env:env_ty) : (bexp R) -> Prop -> Prop :=
207
208
209
210
211
212
213
214
  leq_eval (e1:exp R) (e2:exp R) (v1:R) (v2:R):
    eval_exp eps env e1 v1 ->
    eval_exp eps env e2 v2 ->
    bval eps env (leq e1 e2) (Rle v1 v2)
|less_eval (e1:exp R) (e2:exp R) (v1:R) (v2:R):
    eval_exp eps env e1 v1 ->
    eval_exp eps env e2 v2 ->
    bval eps env (less e1 e2) (Rlt v1 v2).
215
216
217
218
219
(**
 Simplify arithmetic later by making > >= only abbreviations
**)
Definition gr := fun (V:Type) (e1: exp V) (e2: exp V) => less e2 e1.
Definition greq := fun (V:Type) (e1:exp V) (e2: exp V) => leq e2 e1.