(* Specifications: *)
Lemma low_high_u: forall n, Int.or (Int.shl (high_u n) (Int.repr 16)) (low_u n) = n.
Lemma low_high_u_xor: forall n, Int.xor (Int.shl (high_u n) (Int.repr 16)) (low_u n) = n.
Lemma low_high_s: forall n, Int.add (Int.shl (high_s n) (Int.repr 16)) (low_s n) = n.
Lemma add_zero_symbol_address: forall (ge: genv) id ofs, Val.add Vzero (Genv.symbol_address ge id ofs) = Genv.symbol_address ge id ofs.
Lemma low_high_half_zero: forall (ge: genv) id ofs, Val.add (Val.add Vzero (high_half ge id ofs)) (low_half ge id ofs) = Genv.symbol_address ge id ofs.
Lemma get_op_sound: forall v op vl, get v = Some (Op op vl) -> eval_operation ge sp op (map valu vl) m = Some (valu v).
Theorem transf_c_program_preservation: forall p tp beh, transf_c_program p = OK tp -> program_behaves (Asm.semantics tp) beh -> exists beh', program_behaves (Csem.semantics p) beh' /\ behavior_improves beh' beh.
Theorem transf_c_program_is_refinement: forall p tp, transf_c_program p = OK tp -> (forall beh, program_behaves (Csem.semantics p) beh -> not_wrong beh) -> (forall beh, program_behaves (Asm.semantics tp) beh -> program_behaves (Csem.semantics p) beh).
Theorem transf_cstrategy_program_preservation: forall p tp, transf_c_program p = OK tp -> (forall beh, program_behaves (Cstrategy.semantics p) beh -> exists beh', program_behaves (Asm.semantics tp) beh' /\ behavior_improves beh beh') /\(forall beh, program_behaves (Asm.semantics tp) beh -> exists beh', program_behaves (Cstrategy.semantics p) beh' /\ behavior_improves beh' beh) /\(forall beh, not_wrong beh -> program_behaves (Cstrategy.semantics p) beh -> program_behaves (Asm.semantics tp) beh) /\(forall beh, (forall beh', program_behaves (Cstrategy.semantics p) beh' -> not_wrong beh') -> program_behaves (Asm.semantics tp) beh -> program_behaves (Cstrategy.semantics p) beh).
Theorem bigstep_cstrategy_preservation: forall p tp, transf_c_program p = OK tp -> (forall t r, Cstrategy.bigstep_program_terminates p t r -> program_behaves (Asm.semantics tp) (Terminates t r)) /\(forall T, Cstrategy.bigstep_program_diverges p T -> program_behaves (Asm.semantics tp) (Reacts T) \/ exists t, program_behaves (Asm.semantics tp) (Diverges t) /\ traceinf_prefix t T).
Lemma funenv_program_compat: forall p, fenv_compat p (funenv_program p).
Lemma fenv_compat_linkorder: forall cunit prog fenv, linkorder cunit prog -> fenv_compat cunit fenv -> fenv_compat prog fenv.
Lemma shiftpos_eq: forall x y, Zpos (shiftpos x y) = (Zpos x + Zpos y) - 1.
Lemma shiftpos_inj: forall x y n, shiftpos x n = shiftpos y n -> x = y.
Lemma shiftpos_diff: forall x y n, x <> y -> shiftpos x n <> shiftpos y n.
Lemma shiftpos_above: forall x n, Ple n (shiftpos x n).
Lemma shiftpos_not_below: forall x n, Plt (shiftpos x n) n -> False.
Lemma shiftpos_below: forall x n, Plt (shiftpos x n) (Pos.add x n).
Lemma shiftpos_le: forall x y n, Ple x y -> Ple (shiftpos x n) (shiftpos y n).
Lemma loc_arguments_acceptable_2: forall s l, In l (regs_of_rpairs (loc_arguments s)) -> loc_argument_acceptable l.
Lemma init_mapping_wf: map_wf init_mapping.
Lemma add_var_wf: forall s1 s2 map name r map' i, add_var map name s1 = OK (r,map') s2 i -> map_wf map -> map_valid map s1 -> map_wf map'.
Lemma add_vars_wf: forall names s1 s2 map map' rl i, add_vars map names s1 = OK (rl,map') s2 i -> map_wf map -> map_valid map s1 -> map_wf map'.
Lemma add_letvar_wf: forall map r, map_wf map -> ~reg_in_map map r -> map_wf (add_letvar map r).
Lemma match_env_update_res: forall map res v e le tres tv rs, Val.lessdef v tv -> map_wf map -> tr_builtin_res map res tres -> match_env map e le rs -> match_env map (set_builtin_res res v e) le (regmap_setres tres tv rs).
Lemma match_env_unbind_letvar: forall map e le rs r v, match_env (add_letvar map r) e (v :: le) rs -> match_env map e le rs.
Lemma match_env_empty: forall map, map.(map_letvars) = nil -> match_env map (PTree.empty val) nil (Regmap.init Vundef).
Lemma match_init_env_init_reg: forall params s0 rparams map1 s1 i1 vars rvars map2 s2 i2 vparams tvparams, add_vars init_mapping params s0 = OK (rparams, map1) s1 i1 -> add_vars map1 vars s1 = OK (rvars, map2) s2 i2 -> Val.lessdef_list vparams tvparams -> match_env map2 (set_locals vars (set_params vparams params)) nil (init_regs tvparams rparams).
Lemma ireg_of_eq: forall r r', ireg_of r = OK r' -> preg_of r = IR r'.
Lemma freg_of_eq: forall r r', freg_of r = OK r' -> preg_of r = FR r'.
Lemma preg_of_injective: forall r1 r2, preg_of r1 = preg_of r2 -> r1 = r2.
Lemma preg_of_data: forall r, data_preg (preg_of r) = true.
Lemma data_diff: forall r r', data_preg r = true -> data_preg r' = false -> r <> r'.
Lemma preg_of_not_SP: forall r, preg_of r <> SP.
Lemma preg_of_not_PC: forall r, preg_of r <> PC.
Lemma undef_regs_other: forall r rl rs, (forall r', In r' rl -> r <> r') -> undef_regs rl rs r = rs r.
Lemma Zdiv_mul_pos: forall m l, l >= 0 -> two_p (N+l) <= m * d <= two_p (N+l) + two_p l -> forall n, 0 <= n < two_p N -> Z.div n d = Z.div (m * n) (two_p (N + l)).
Lemma Zdiv_unique_2: forall x y q, y > 0 -> 0 < y * q - x <= y -> Z.div x y = q - 1.
Lemma Zdiv_mul_opp: forall m l, l >= 0 -> two_p (N+l) < m * d <= two_p (N+l) + two_p l -> forall n, 0 < n <= two_p N -> Z.div n d = - Z.div (m * (-n)) (two_p (N + l)) - 1.
Lemma Zquot_mul: forall m l, l >= 0 -> two_p (N+l) < m * d <= two_p (N+l) + two_p l -> forall n, - two_p N <= n < two_p N -> Z.quot n d = Z.div (m * n) (two_p (N + l)) + (if zlt n 0 then 1 else 0).
Lemma divs_mul_params_sound: forall d m p, divs_mul_params d = Some(p, m) -> 0 <= m < Int.modulus /\ 0 <= p < 32 /\ forall n, Int.min_signed <= n <= Int.max_signed -> Z.quot n d = Z.div (m * n) (two_p (32 + p)) + (if zlt n 0 then 1 else 0).
Lemma divu_mul_params_sound: forall d m p, divu_mul_params d = Some(p, m) -> 0 <= m < Int.modulus /\ 0 <= p < 32 /\ forall n, 0 <= n < Int.modulus -> Z.div n d = Z.div (m * n) (two_p (32 + p)).
Lemma divs_mul_shift_gen: forall x y m p, divs_mul_params (Int.signed y) = Some(p, m) -> 0 <= m < Int.modulus /\ 0 <= p < 32 /\ Int.divs x y = Int.add (Int.shr (Int.repr ((Int.signed x * m) / Int.modulus)) (Int.repr p)) (Int.shru x (Int.repr 31)).
Theorem divs_mul_shift_1: forall x y m p, divs_mul_params (Int.signed y) = Some(p, m) -> m < Int.half_modulus -> 0 <= p < 32 /\ Int.divs x y = Int.add (Int.shr (Int.mulhs x (Int.repr m)) (Int.repr p)) (Int.shru x (Int.repr 31)).
Theorem divs_mul_shift_2: forall x y m p, divs_mul_params (Int.signed y) = Some(p, m) -> m >= Int.half_modulus -> 0 <= p < 32 /\ Int.divs x y = Int.add (Int.shr (Int.add (Int.mulhs x (Int.repr m)) x) (Int.repr p)) (Int.shru x (Int.repr 31)).
Theorem divu_mul_shift: forall x y m p, divu_mul_params (Int.unsigned y) = Some(p, m) -> 0 <= p < 32 /\ Int.divu x y = Int.shru (Int.mulhu x (Int.repr m)) (Int.repr p).
Lemma divls_mul_params_sound: forall d m p, divls_mul_params d = Some(p, m) -> 0 <= m < Int64.modulus /\ 0 <= p < 64 /\ forall n, Int64.min_signed <= n <= Int64.max_signed -> Z.quot n d = Z.div (m * n) (two_p (64 + p)) + (if zlt n 0 then 1 else 0).
Lemma divlu_mul_params_sound: forall d m p, divlu_mul_params d = Some(p, m) -> 0 <= m < Int64.modulus /\ 0 <= p < 64 /\ forall n, 0 <= n < Int64.modulus -> Z.div n d = Z.div (m * n) (two_p (64 + p)).
Lemma agree_nextinstr_nf: forall ms sp rs, agree ms sp rs -> agree ms sp (nextinstr_nf rs).
Lemma get_op_sound: forall v op vl, get v = Some (Op op vl) -> eval_operation ge sp op (map valu vl) m = Some (valu v).
Lemma functional_extensionality_dep: forall {A: Type} {B : A -> Type} (f g : forall x : A, B x), (forall x, f x = g x) -> f = g.
Lemma functional_extensionality: forall {A B: Type} (f g : A -> B), (forall x, f x = g x) -> f = g.
Lemma extensionality: forall {A B: Type} (f g : A -> B), (forall x, f x = g x) -> f = g.
Lemma ireg_of_not_R14: forall m r, ireg_of m = OK r -> IR r <> IR IR14.
Lemma ireg_of_not_R14': forall m r, ireg_of m = OK r -> r <> IR14.
Lemma get_op_sound: forall v op vl, get v = Some (Op op vl) -> eval_operation ge sp op (map valu vl) m = Some (valu v).
Theorem Zopp_le_cancel : forall x y : Z, (-y <= -x)%Z -> Zle x y.
Theorem Zgt_not_eq : forall x y : Z, (y < x)%Z -> (x <> y)%Z.
Theorem round_val_of_pred : forall rnd : R -> R -> Prop, round_pred rnd -> forall x, { f : R | rnd x f }.
Theorem round_fun_of_pred : forall rnd : R -> R -> Prop, round_pred rnd -> { f : R -> R | forall x, rnd x (f x) }.
Theorem round_unicity : forall rnd : R -> R -> Prop, round_pred_monotone rnd -> forall x f1 f2, rnd x f1 -> rnd x f2 -> f1 = f2.
Theorem Rnd_DN_pt_monotone : forall F : R -> Prop, round_pred_monotone (Rnd_DN_pt F).
Theorem Rnd_DN_pt_unicity : forall F : R -> Prop, forall x f1 f2 : R, Rnd_DN_pt F x f1 -> Rnd_DN_pt F x f2 -> f1 = f2.
Theorem Rnd_DN_unicity : forall F : R -> Prop, forall rnd1 rnd2 : R -> R, Rnd_DN F rnd1 -> Rnd_DN F rnd2 -> forall x, rnd1 x = rnd2 x.
Theorem Rnd_UP_pt_monotone : forall F : R -> Prop, round_pred_monotone (Rnd_UP_pt F).
Theorem Rnd_UP_pt_unicity : forall F : R -> Prop, forall x f1 f2 : R, Rnd_UP_pt F x f1 -> Rnd_UP_pt F x f2 -> f1 = f2.
Theorem Rnd_UP_unicity : forall F : R -> Prop, forall rnd1 rnd2 : R -> R, Rnd_UP F rnd1 -> Rnd_UP F rnd2 -> forall x, rnd1 x = rnd2 x.
Theorem Rnd_DN_UP_pt_sym : forall F : R -> Prop, ( forall x, F x -> F (- x) ) -> forall x f : R, Rnd_DN_pt F x f -> Rnd_UP_pt F (-x) (-f).
Theorem Rnd_UP_DN_pt_sym : forall F : R -> Prop, ( forall x, F x -> F (- x) ) -> forall x f : R, Rnd_UP_pt F x f -> Rnd_DN_pt F (-x) (-f).
Theorem Rnd_DN_UP_sym : forall F : R -> Prop, ( forall x, F x -> F (- x) ) -> forall rnd1 rnd2 : R -> R, Rnd_DN F rnd1 -> Rnd_UP F rnd2 -> forall x, rnd1 (- x) = - rnd2 x.
Theorem Rnd_DN_UP_pt_split : forall F : R -> Prop, forall x d u, Rnd_DN_pt F x d -> Rnd_UP_pt F x u -> forall f, F f -> (f <= d) \/ (u <= f).
Theorem Rnd_DN_pt_refl : forall F : R -> Prop, forall x : R, F x -> Rnd_DN_pt F x x.
Theorem Rnd_DN_pt_idempotent : forall F : R -> Prop, forall x f : R, Rnd_DN_pt F x f -> F x -> f = x.
Theorem Rnd_UP_pt_refl : forall F : R -> Prop, forall x : R, F x -> Rnd_UP_pt F x x.
Theorem Rnd_UP_pt_idempotent : forall F : R -> Prop, forall x f : R, Rnd_UP_pt F x f -> F x -> f = x.
Theorem Only_DN_or_UP : forall F : R -> Prop, forall x fd fu f : R, Rnd_DN_pt F x fd -> Rnd_UP_pt F x fu -> F f -> (fd <= f <= fu)%R -> f = fd \/ f = fu.
Theorem Rnd_ZR_abs : forall (F : R -> Prop) (rnd: R-> R), Rnd_ZR F rnd -> forall x : R, (Rabs (rnd x) <= Rabs x)%R.
Theorem Rnd_ZR_pt_monotone : forall F : R -> Prop, F 0 -> round_pred_monotone (Rnd_ZR_pt F).
Theorem Rnd_N_pt_DN_or_UP : forall F : R -> Prop, forall x f : R, Rnd_N_pt F x f -> Rnd_DN_pt F x f \/ Rnd_UP_pt F x f.
Theorem Rnd_N_pt_DN_or_UP_eq : forall F : R -> Prop, forall x fd fu f : R, Rnd_DN_pt F x fd -> Rnd_UP_pt F x fu -> Rnd_N_pt F x f -> f = fd \/ f = fu.
Theorem Rnd_N_pt_sym : forall F : R -> Prop, ( forall x, F x -> F (- x) ) -> forall x f : R, Rnd_N_pt F (-x) (-f) -> Rnd_N_pt F x f.
Theorem Rnd_N_pt_monotone : forall F : R -> Prop, forall x y f g : R, Rnd_N_pt F x f -> Rnd_N_pt F y g -> x < y -> f <= g.
Theorem Rnd_N_pt_unicity : forall F : R -> Prop, forall x d u f1 f2 : R, Rnd_DN_pt F x d -> Rnd_UP_pt F x u -> x - d <> u - x -> Rnd_N_pt F x f1 -> Rnd_N_pt F x f2 -> f1 = f2.
Theorem Rnd_N_pt_refl : forall F : R -> Prop, forall x : R, F x -> Rnd_N_pt F x x.
Theorem Rnd_N_pt_idempotent : forall F : R -> Prop, forall x f : R, Rnd_N_pt F x f -> F x -> f = x.
Theorem Rnd_N_pt_0 : forall F : R -> Prop, F 0 -> Rnd_N_pt F 0 0.
Theorem Rnd_N_pt_pos : forall F : R -> Prop, F 0 -> forall x f, 0 <= x -> Rnd_N_pt F x f -> 0 <= f.
Theorem Rnd_N_pt_neg : forall F : R -> Prop, F 0 -> forall x f, x <= 0 -> Rnd_N_pt F x f -> f <= 0.
Theorem Rnd_N_pt_abs : forall F : R -> Prop, F 0 -> ( forall x, F x -> F (- x) ) -> forall x f : R, Rnd_N_pt F x f -> Rnd_N_pt F (Rabs x) (Rabs f).
Theorem Rnd_DN_UP_pt_N : forall F : R -> Prop, forall x d u f : R, F f -> Rnd_DN_pt F x d -> Rnd_UP_pt F x u -> (Rabs (f - x) <= x - d)%R -> (Rabs (f - x) <= u - x)%R -> Rnd_N_pt F x f.
Theorem Rnd_DN_pt_N : forall F : R -> Prop, forall x d u : R, Rnd_DN_pt F x d -> Rnd_UP_pt F x u -> (x - d <= u - x)%R -> Rnd_N_pt F x d.
Theorem Rnd_UP_pt_N : forall F : R -> Prop, forall x d u : R, Rnd_DN_pt F x d -> Rnd_UP_pt F x u -> (u - x <= x - d)%R -> Rnd_N_pt F x u.
Theorem Rle_0_minus : forall x y, (x <= y)%R -> (0 <= y - x)%R.
Theorem Rabs_eq_Rabs : forall x y : R, Rabs x = Rabs y -> x = y \/ x = Ropp y.
Theorem Rabs_minus_le: forall x y : R, (0 <= y)%R -> (y <= 2*x)%R -> (Rabs (x-y) <= x)%R.
Theorem Rplus_eq_reg_r : forall r r1 r2 : R, (r1 + r = r2 + r)%R -> (r1 = r2)%R.
Theorem Rplus_lt_reg_l : forall r r1 r2 : R, (r + r1 < r + r2)%R -> (r1 < r2)%R.
Theorem Rplus_lt_reg_r : forall r r1 r2 : R, (r1 + r < r2 + r)%R -> (r1 < r2)%R.
Theorem Rplus_le_reg_r : forall r r1 r2 : R, (r1 + r <= r2 + r)%R -> (r1 <= r2)%R.
Theorem Rmult_lt_reg_r : forall r r1 r2 : R, (0 < r)%R -> (r1 * r < r2 * r)%R -> (r1 < r2)%R.
Theorem Rmult_le_reg_r : forall r r1 r2 : R, (0 < r)%R -> (r1 * r <= r2 * r)%R -> (r1 <= r2)%R.
Theorem Rmult_lt_compat : forall r1 r2 r3 r4, (0 <= r1)%R -> (0 <= r3)%R -> (r1 < r2)%R -> (r3 < r4)%R -> (r1 * r3 < r2 * r4)%R.
Theorem Rmult_eq_reg_r : forall r r1 r2 : R, (r1 * r)%R = (r2 * r)%R -> r <> 0%R -> r1 = r2.
Theorem Rmult_minus_distr_r : forall r r1 r2 : R, ((r1 - r2) * r = r1 * r - r2 * r)%R.
Lemma Rmult_neq_reg_r: forall r1 r2 r3:R, (r2 * r1 <> r3 * r1)%R -> r2 <> r3.
Lemma Rmult_neq_compat_r: forall r1 r2 r3:R, (r1 <> 0)%R -> (r2 <> r3)%R -> (r2 *r1 <> r3*r1)%R.
Theorem Rmult_min_distr_r : forall r r1 r2 : R, (0 <= r)%R -> (Rmin r1 r2 * r)%R = Rmin (r1 * r) (r2 * r).
Theorem Rmult_min_distr_l : forall r r1 r2 : R, (0 <= r)%R -> (r * Rmin r1 r2)%R = Rmin (r * r1) (r * r2).
Lemma Rmin_opp: forall x y, (Rmin (-x) (-y) = - Rmax x y)%R.
Lemma Rmax_opp: forall x y, (Rmax (-x) (-y) = - Rmin x y)%R.
Theorem exp_le : forall x y : R, (x <= y)%R -> (exp x <= exp y)%R.
Theorem Rinv_lt : forall x y, (0 < x)%R -> (x < y)%R -> (/y < /x)%R.
Theorem Rinv_le : forall x y, (0 < x)%R -> (x <= y)%R -> (/y <= /x)%R.
Theorem sqrt_ge_0 : forall x : R, (0 <= sqrt x)%R.
Lemma sqrt_neg : forall x, (x <= 0)%R -> (sqrt x = 0)%R.
Theorem Rabs_le : forall x y, (-y <= x <= y)%R -> (Rabs x <= y)%R.
Theorem Rabs_le_inv : forall x y, (Rabs x <= y)%R -> (-y <= x <= y)%R.
Theorem Rabs_ge : forall x y, (y <= -x \/ x <= y)%R -> (x <= Rabs y)%R.
Theorem Rabs_ge_inv : forall x y, (x <= Rabs y)%R -> (y <= -x \/ x <= y)%R.
Theorem Rabs_lt : forall x y, (-y < x < y)%R -> (Rabs x < y)%R.
Theorem Rabs_lt_inv : forall x y, (Rabs x < y)%R -> (-y < x < y)%R.
Theorem Rabs_gt : forall x y, (y < -x \/ x < y)%R -> (x < Rabs y)%R.
Theorem Rabs_gt_inv : forall x y, (x < Rabs y)%R -> (y < -x \/ x < y)%R.
Lemma pop_invariant_converter: forall A symbols_to_pop symbols_popped, arrows_left (map symbol_semantic_type (rev_append symbols_to_pop symbols_popped)) A = arrows_left (map symbol_semantic_type symbols_popped) (arrows_right A (map symbol_semantic_type symbols_to_pop)).
Lemma pop_invariant: forall (symbols_to_pop symbols_popped:list symbol) (stack_cur:stack) (A:Type) (action:arrows_left (map symbol_semantic_type (rev_append symbols_to_pop symbols_popped)) A), forall word_stack word_popped, forall sem_popped, word_has_stack_semantics word_stack stack_cur -> inhabited (parse_tree_list symbols_popped word_popped sem_popped) -> let action' := eq_rect _ (fun x=>x) action _ (pop_invariant_converter _ _ _) in match pop symbols_to_pop stack_cur (uncurry action' sem_popped) with | OK (stack_new, sem) => exists word1res word2res sem_full, (word_stack = word1res ++ word2res)%list /\ word_has_stack_semantics word1res stack_new /\ sem = uncurry action sem_full /\ inhabited ( parse_tree_list (rev_append symbols_to_pop symbols_popped) (word2res++word_popped) sem_full) | Err => True end.
Lemma reduce_step_invariant (stack:stack) (prod:production): forall word buffer, word_has_stack_semantics word stack -> match reduce_step init stack prod buffer with | OK (Accept_sr sem buffer_new) => buffer = buffer_new /\ inhabited (parse_tree (NT (start_nt init)) word sem) | OK (Progress_sr stack_new buffer_new) => buffer = buffer_new /\ word_has_stack_semantics word stack_new | Err | OK Fail_sr => True end.
Lemma step_invariant (stack:stack) (buffer:Stream token): forall buffer_tmp, (exists word_old, buffer = word_old ++ buffer_tmp /\ word_has_stack_semantics word_old stack) -> match step init stack buffer_tmp with | OK (Accept_sr sem buffer_new) => exists word_new, buffer = word_new ++ buffer_new /\ inhabited (parse_tree (NT (start_nt init)) word_new sem) | OK (Progress_sr stack_new buffer_new) => exists word_new, buffer = word_new ++ buffer_new /\ word_has_stack_semantics word_new stack_new | Err | OK Fail_sr => True end.
Theorem parse_correct buffer n_steps: match parse init buffer n_steps with | OK (Parsed_pr sem buffer_new) => exists word_new, buffer = word_new ++ buffer_new /\ inhabited (parse_tree (NT (start_nt init)) word_new sem) | _ => True end.
Lemma make_immed32_sound: forall n, match make_immed32 n with | Imm32_single imm => n = imm | Imm32_pair hi lo => n = Int.add (Int.shl hi (Int.repr 12)) lo end.
Lemma make_immed64_sound: forall n, match make_immed64 n with | Imm64_single imm => n = imm | Imm64_pair hi lo => n = Int64.add (Int64.sign_ext 32 (Int64.shl hi (Int64.repr 12))) lo | Imm64_large imm => n = imm end.
Lemma ireg_of_not_X31: forall m r, ireg_of m = OK r -> IR r <> IR X31.
Lemma ireg_of_not_X31': forall m r, ireg_of m = OK r -> r <> X31.
Lemma get_op_sound: forall v op vl, get v = Some (Op op vl) -> eval_operation ge sp op (map valu vl) m = Some (valu v).