SilverSight/formal/SilverSight/WireFormat.lean
allaun 4f7c554981 feat(core): add Phase 1 SilverSight core modules
New modules in formal/SilverSight/:
- Schema.lean: Schema class with 6 type instances
- WireFormat.lean: WireFormat structure + Layout enum
- ProductSchema.lean: Schema (α × β) instance
- ProductWireFormat.lean: Row-major pair encoders
- Receipt.lean: Receipt structure + GateType enum
- Bind.lean: bindReceipt composition primitive

Build: 3307 jobs, 0 errors (from Research Stack lake build SilverSight)
All modules use Semantics.FixedPoint cross-project import.
2026-06-22 21:48:15 -05:00

74 lines
3.7 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SilverSight.Schema
namespace SilverSight
open Semantics.FixedPoint
-- ═══════════════════════════════════════════════════════════════════════════
-- §1 Layout enum
-- ═══════════════════════════════════════════════════════════════════════════
/-- Layout describes how fields are arranged in a wire encoding.
- `rowMajor`: fields stored in declaration order (a₀, a₁, …, b₀, b₁, …)
- `columnar`: fields stored contiguously by field index (a₀, b₀, a₁, b₁, …) -/
inductive Layout where
| rowMajor
| columnar
deriving BEq, DecidableEq, Repr, Inhabited
-- ═══════════════════════════════════════════════════════════════════════════
-- §2 WireFormat structure
-- ═══════════════════════════════════════════════════════════════════════════
/-- A WireFormat certifies the encode/decode cycle for a type under a layout.
The `encode_size` proof ensures every encoded value has exactly `Schema.byteSize α` bytes.
The `roundTrip` proof ensures `decode (encode x) = some x` for all valid `x`. -/
structure WireFormat (α : Type) [Schema α] (L : Layout) where
encode : α → ByteArray
decode : ByteArray → Option α
encode_size : ∀ a : α, (encode a).size = Schema.byteSize α
roundTrip : ∀ a : α, decode (encode a) = some a
-- ═══════════════════════════════════════════════════════════════════════════
-- §3 Basic WireFormat instances
-- ═══════════════════════════════════════════════════════════════════════════
/-- Encode a UInt8 as a single byte.
Roundtrip: encoding then decoding recovers the original value. -/
def uint8RowMajor : WireFormat UInt8 Layout.rowMajor where
encode := fun u => ByteArray.mk #[u]
decode := fun bs =>
if h : bs.size = 1 then some (bs.get! 0)
else none
encode_size := by intro a; simp [ByteArray.size]
roundTrip := by
intro a
simp only [ByteArray.size]
have h1 : (ByteArray.mk #[a]).size = 1 := by simp [ByteArray.size]
simp [h1]
rfl
#eval uint8RowMajor.encode 42 -- expected: ByteArray with single byte 42
#eval uint8RowMajor.decode (uint8RowMajor.encode 42) -- expected: some 42
/-- Encode a Bool as a single byte (0=false, 1=true).
Uses revert + native_decide for the roundtrip proof since Bool is finite. -/
def boolRowMajor : WireFormat Bool Layout.rowMajor where
encode := fun b => ByteArray.mk #[if b then 1 else 0]
decode := fun bs =>
if h : bs.size = 1 then
let b := bs.get! 0
some (b != 0)
else none
encode_size := by intro a; simp [ByteArray.size]
roundTrip := by
intro a
revert a
native_decide
#eval boolRowMajor.encode true -- expected: ByteArray with single byte 1
#eval boolRowMajor.encode false -- expected: ByteArray with single byte 0
#eval boolRowMajor.decode (boolRowMajor.encode true) -- expected: some true
#eval boolRowMajor.decode (boolRowMajor.encode false) -- expected: some false
end SilverSight