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.