include "common/ByteValues.ma". (* dpm: Can these two inductive definitions be merged? In LIN, yes, but perhaps not further back in the translation chain. *) inductive OpAccs: Type[0] ≝ Mul: OpAccs | DivuModu: OpAccs. inductive Op1: Type[0] ≝ Cmpl: Op1 | Inc: Op1 | Rl: Op1. (* TODO: implement left rotation *) inductive Op2: Type[0] ≝ Add: Op2 | Addc: Op2 | Sub: Op2 | And: Op2 | Or: Op2 | Xor: Op2. record Eval : Type[0] ≝ { opaccs: OpAccs → Byte → Byte → Byte × Byte; op1: Op1 → Byte → Byte; op2: Bit → Op2 → Byte → Byte → (Byte × Bit) }. axiom opaccs_implementation: OpAccs → Byte → Byte → Byte × Byte. axiom op1_implementation: Op1 → Byte → Byte. axiom op2_implementation: Bit → Op2 → Byte → Byte → (Byte × Bit). definition eval : Eval ≝ mk_Eval opaccs_implementation op1_implementation op2_implementation. axiom UnsupportedOp : String. definition be_opaccs : OpAccs → beval → beval → res (beval × beval) ≝ λop,a,b. ! a' ← Byte_of_val UnsupportedOp a ; ! b' ← Byte_of_val UnsupportedOp b ; let 〈a'',b''〉 ≝ opaccs eval op a' b' in return 〈BVByte a'', BVByte b''〉. definition be_op1 : Op1 → beval → res beval ≝ λop,a. ! a' ← Byte_of_val UnsupportedOp a ; return BVByte (op1 eval op a'). definition op2_bytes : Op2 → ∀n.Bit → Vector Byte n → Vector Byte n → (Vector Byte n) × Bit ≝ λop,n,carry. let f ≝ λn,b1,b2.λpr : (Vector Byte n) × Bit. let 〈res_tl, carry〉 ≝ pr in let 〈res_hd,carry'〉 ≝ op2 eval carry op b1 b2 in 〈res_hd ::: res_tl, carry'〉 in fold_right2_i … f 〈[[ ]],carry〉 n. definition be_add_sub_byte : bool → bebit → beval → Byte → res (beval × bebit) ≝ λis_add,carry,a1,b2. let op ≝ if is_add then Addc else Sub in match a1 with [ BVByte b1 ⇒ ! carry' ← Bit_of_val UnsupportedOp carry ; let 〈rslt, carry''〉 ≝ op2 eval carry' op b1 b2 in return 〈BVByte rslt, BBbit carry''〉 | BVptr ptr p ⇒ match ptype ptr with [ Code ⇒ Error … [MSG UnsupportedOp] | XData ⇒ match p with [ O ⇒ ! carry' ← Bit_of_val UnsupportedOp carry ; if carry' then Error … [MSG UnsupportedOp] else let o1o0 : Byte × Byte ≝ vsplit ? 8 8 (offv (poff ptr)) in let 〈rslt,carry〉 ≝ op2 eval false op b2 (\snd o1o0) in let p0 ≝ mk_part 0 (le_S … (le_n …)) in let ptr' ≝ mk_pointer (pblock ptr) (mk_offset (\fst o1o0 @@ rslt)) in return 〈BVptr ptr' p, BBptrcarry is_add ptr p0 b2〉 | _ ⇒ (* it is 1. To generalize, many casts ⌈…⌉ needs to be added *) match carry with [ BBptrcarry is_add' ptr' p' by' ⇒ if eq_b is_add is_add' ∧ eq_block (pblock ptr) (pblock ptr') ∧ eq_bv_suffix 8 8 8 (offv (poff ptr)) (offv (poff ptr')) then If eqb p' 0 then with prf do let by' : Byte ≝ by' ⌈? ↦ Byte⌉ in let o1o0 ≝ vsplit ? 8 8 (offv (poff ptr)) in let o1o0 ≝ [[\fst o1o0 ; \snd o1o0]] in let 〈rslt,ignore〉 ≝ op2_bytes op ? false o1o0 [[b2 ; by']] in let part1 ≝ mk_part 1 (le_n …) in let ptr' ≝ mk_pointer (pblock ptr) (mk_offset (vflatten … rslt)) in OK … 〈BVptr ptr' part1, BBptrcarry is_add ptr' part1 (b2 @@ by')〉 else Error … [MSG UnsupportedOp] else Error … [MSG UnsupportedOp] | _ ⇒ Error … [MSG UnsupportedOp] ] ] ] | _ ⇒ Error … [MSG UnsupportedOp] ]. @hide_prf lapply prf @(eqb_elim p') #H * >H % qed. definition byte_at : ∀n.BitVector (8*n) → ∀p.p < n → Byte ≝ λn,v,p,H. let suffix : BitVector (8 + 8*p) ≝ \snd (vsplit … (v⌈BitVector ?↦BitVector (8*(n - S p) + (8 + 8*p))⌉)) in \fst (vsplit … suffix). >(commutative_times_fast ? p) change with (? = BitVector (? + S p*8)) >(commutative_times_fast (S p))