"""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