mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
204 lines
7.4 KiB
Text
204 lines
7.4 KiB
Text
import Mathlib.Data.Set.Basic
|
||
import Semantics.AVM
|
||
import Semantics.SidonSet
|
||
|
||
namespace Semantics.SidonAVM
|
||
|
||
open Semantics
|
||
open Semantics.AVM
|
||
open Semantics.SidonSet
|
||
|
||
/-! # Sidon AVM — Greedy Erdős–Turán Construction
|
||
|
||
This module implements the greedy Sidon set generator as an AVM program.
|
||
The AVM state encodes the Sidon construction state in memory:
|
||
M[0] = target size (k)
|
||
M[1] = current length
|
||
M[2..9] = current elements (max 8 slots for braid strands)
|
||
M[10] = candidate
|
||
M[11] = canAdd result (1 = yes, 0 = no)
|
||
M[12] = loop index i
|
||
M[13] = loop index j
|
||
M[14] = temp sum
|
||
M[15] = temp flag
|
||
-/
|
||
|
||
/-- Maximum Sidon set size supported by this AVM program (8 braid strands). -/
|
||
def maxSidonSize : Nat := 8
|
||
|
||
/-- Memory layout constants. -/
|
||
def memTarget : Nat := 0
|
||
def memCurrentLen : Nat := 1
|
||
def memCurrentBase : Nat := 2
|
||
def memCandidate : Nat := 10
|
||
def memCanAdd : Nat := 11
|
||
def memLoopI : Nat := 12
|
||
def memLoopJ : Nat := 13
|
||
def memTempSum : Nat := 14
|
||
def memTempFlag : Nat := 15
|
||
|
||
/-- Initialize AVM memory for Sidon generation. -/
|
||
def initMemory (target : Nat) : Array Value :=
|
||
let mem := Array.mk (List.replicate 20 (Value.int 0))
|
||
let mem := setMemory mem memTarget (Value.int target)
|
||
let mem := setMemory mem memCurrentLen (Value.int 1)
|
||
let mem := setMemory mem memCurrentBase (Value.int 1)
|
||
let mem := setMemory mem memCandidate (Value.int 2)
|
||
mem
|
||
|
||
/-- Read a Nat from memory at given address. Returns 0 if not an int. -/
|
||
def readNat (mem : Array Value) (addr : Nat) : Nat :=
|
||
match mem[addr]? with
|
||
| some (Value.int n) => n.toNat
|
||
| _ => 0
|
||
|
||
/-- Read current Sidon elements from memory as a List Nat. -/
|
||
def readCurrent (mem : Array Value) : List Nat :=
|
||
let len := readNat mem memCurrentLen
|
||
(List.range len).map (fun i => readNat mem (memCurrentBase + i))
|
||
|
||
/-- Read the candidate from memory. -/
|
||
def readCandidate (mem : Array Value) : Nat :=
|
||
readNat mem memCandidate
|
||
|
||
/-- Check if the greedy Sidon construction is complete. -/
|
||
def sidonCheckDone (s : State) : State :=
|
||
let target := readNat s.memory memTarget
|
||
let len := readNat s.memory memCurrentLen
|
||
if len ≥ target then { s with halted := true } else s
|
||
|
||
/-- Check if candidate can be added to the current Sidon set.
|
||
Uses the pure Lean `canAdd` function. -/
|
||
def sidonTryAdd (s : State) : State :=
|
||
let current := readCurrent s.memory
|
||
let candidate := readCandidate s.memory
|
||
if canAdd current candidate then
|
||
let len := readNat s.memory memCurrentLen
|
||
let mem := setMemory s.memory (memCurrentBase + len) (Value.int candidate)
|
||
let mem := setMemory mem memCurrentLen (Value.int (len + 1))
|
||
{ s with memory := mem }
|
||
else s
|
||
|
||
/-- Increment the candidate. -/
|
||
def sidonIncrementCandidate (s : State) : State :=
|
||
let c := readCandidate s.memory
|
||
{ s with memory := setMemory s.memory memCandidate (Value.int (c + 1)) }
|
||
|
||
/-- Sidon-specific step handler. Extends generic AVM step with
|
||
method calls for Sidon operations. -/
|
||
def sidonStep (s : State) : State :=
|
||
if s.halted then s
|
||
else match s.program[s.pc]? with
|
||
| some (Instruction.call "sidonCheckDone") =>
|
||
sidonCheckDone { s with pc := s.pc + 1 }
|
||
| some (Instruction.call "sidonTryAdd") =>
|
||
sidonTryAdd { s with pc := s.pc + 1 }
|
||
| some (Instruction.call "sidonIncrementCandidate") =>
|
||
sidonIncrementCandidate { s with pc := s.pc + 1 }
|
||
| _ => step s
|
||
|
||
/-- Run Sidon AVM with fuel. -/
|
||
def sidonRun (s : State) (fuel : Nat) : State :=
|
||
match fuel with
|
||
| 0 => s
|
||
| fuel' + 1 =>
|
||
let s' := sidonStep s
|
||
if s'.halted then s' else sidonRun s' fuel'
|
||
|
||
/-- AVM program for greedy Sidon generation.
|
||
Loop: checkDone → tryAdd → incrementCandidate → jump back. -/
|
||
def sidonProgram : Array Instruction := #[
|
||
Instruction.call "sidonCheckDone",
|
||
Instruction.call "sidonTryAdd",
|
||
Instruction.call "sidonIncrementCandidate",
|
||
Instruction.jump 0,
|
||
Instruction.halt
|
||
]
|
||
|
||
/-- Create initial AVM state for generating a Sidon set of size target. -/
|
||
def sidonInitialState (target : Nat) : State :=
|
||
{ stack := [], pc := 0, memory := initMemory target,
|
||
program := sidonProgram, halted := false }
|
||
|
||
/-- Extract the generated Sidon set from the final AVM state. -/
|
||
def extractSidonSet (s : State) : List Nat :=
|
||
readCurrent s.memory
|
||
|
||
/-- Compuatable boolean test for the Sidon property. -/
|
||
def isSidonList (s : List Nat) : Bool :=
|
||
let sums := pairwiseSums s
|
||
sums.length == sums.eraseDups.length
|
||
|
||
/-- Receipt for one Sidon AVM step. -/
|
||
structure SidonReceipt where
|
||
stepCount : Nat
|
||
pc : Nat
|
||
candidate : Nat
|
||
currentLen : Nat
|
||
deriving Repr
|
||
|
||
/-- Generate receipts from an AVM execution trace. -/
|
||
def sidonRunTrace (s : State) (fuel : Nat) (stepCount : Nat := 0)
|
||
: State × List SidonReceipt :=
|
||
match fuel with
|
||
| 0 => (s, [])
|
||
| fuel' + 1 =>
|
||
if s.halted then (s, [])
|
||
else
|
||
let candidate := readCandidate s.memory
|
||
let currentLen := readNat s.memory memCurrentLen
|
||
let receipt := { stepCount := stepCount, pc := s.pc,
|
||
candidate := candidate, currentLen := currentLen }
|
||
let s' := sidonStep s
|
||
let (final_s, rest) := sidonRunTrace s' fuel' (stepCount + 1)
|
||
(final_s, receipt :: rest)
|
||
|
||
-- ═══════════════════════════════════════════════════════════════════════════
|
||
-- §1 Executable Witness
|
||
-- ═══════════════════════════════════════════════════════════════════════════
|
||
|
||
#eval extractSidonSet (sidonRun (sidonInitialState 6) 3600)
|
||
-- Expected: [1, 2, 4, 8, 13, 21]
|
||
|
||
#eval (sidonRun (sidonInitialState 8) 6400).halted
|
||
-- Expected: true
|
||
|
||
-- ═══════════════════════════════════════════════════════════════════════════
|
||
-- §2 Verification Theorems
|
||
-- ═══════════════════════════════════════════════════════════════════════════
|
||
|
||
/-- Computational verification: for small targets, the AVM produces
|
||
the same result as the pure functional generator. -/
|
||
theorem sidonAVM_eq_generateSidonFuel (target : Nat) (h : target ≤ maxSidonSize) :
|
||
let fuel := target * target * 100 + 1
|
||
let initial := sidonInitialState target
|
||
let final := sidonRun initial fuel
|
||
final.halted →
|
||
generateSidonFuel target fuel = some (extractSidonSet final) :=
|
||
by
|
||
unfold maxSidonSize at h
|
||
interval_cases target <;> native_decide
|
||
|
||
/-- The AVM-generated set satisfies the Sidon property. -/
|
||
theorem sidonAVM_isSidonList (target : Nat) (h : target ≤ maxSidonSize) :
|
||
let fuel := target * target * 100 + 1
|
||
let initial := sidonInitialState target
|
||
let final := sidonRun initial fuel
|
||
final.halted →
|
||
isSidonList (extractSidonSet final) = true :=
|
||
by
|
||
unfold maxSidonSize at h
|
||
interval_cases target <;> native_decide
|
||
|
||
/-- Termination bound: the greedy Sidon AVM terminates within
|
||
target² * 100 + 1 steps for target ≤ 8. -/
|
||
theorem sidonAVM_terminates (target : Nat) (h : target ≤ maxSidonSize) :
|
||
let fuel := target * target * 100 + 1
|
||
let initial := sidonInitialState target
|
||
let final := sidonRun initial fuel
|
||
final.halted :=
|
||
by
|
||
unfold maxSidonSize at h
|
||
interval_cases target <;> native_decide
|
||
|
||
end Semantics.SidonAVM
|