polycode-sim/strategies.py
tegwick a8e4f03172
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Complete POLYCODE-WP-0002 simulator v0.1 scaffold
2026-07-08 15:21:15 +02:00

54 lines
No EOL
1.5 KiB
Python

"""Pluggable investor and voter strategies for PolyCode v0.1."""
from __future__ import annotations
import random
from dataclasses import dataclass
from typing import Protocol
@dataclass(frozen=True)
class Proposal:
id: int
effort: float
value: float
class InvestorStrategy(Protocol):
def allocate(
self, proposal: Proposal, funded: float, available: float, rng: random.Random
) -> float: ...
class VoterStrategy(Protocol):
def approve(self, proposal: Proposal, funded: float, rng: random.Random) -> bool: ...
class ThresholdInvestor:
"""Invest when projected value covers effort."""
def allocate(
self, proposal: Proposal, funded: float, available: float, rng: random.Random
) -> float:
if proposal.value < proposal.effort or available <= 0:
return 0.0
need = max(0.0, proposal.effort - funded)
return min(available, need)
class RandomInvestor:
def allocate(
self, proposal: Proposal, funded: float, available: float, rng: random.Random
) -> float:
if available <= 0:
return 0.0
return rng.uniform(0, min(available, max(0.0, proposal.effort - funded)))
class ValueVoter:
def approve(self, proposal: Proposal, funded: float, rng: random.Random) -> bool:
return funded >= proposal.effort and proposal.value >= proposal.effort
class LenientVoter:
def approve(self, proposal: Proposal, funded: float, rng: random.Random) -> bool:
return funded >= proposal.effort * 0.8