From 80c316192956f251970c402d8d65403cf2dc1fcc Mon Sep 17 00:00:00 2001 From: rvcas Date: Tue, 5 Sep 2023 21:52:58 -0400 Subject: [PATCH 1/2] feat: fill in Machine::Run and some budget methods Co-authored-by: Salvionied --- machine.go | 264 +++++++++++++++++++++++++++++++++++++++++++++++++++-- term.go | 13 +++ 2 files changed, 267 insertions(+), 10 deletions(-) diff --git a/machine.go b/machine.go index 2d70024..28ebdbf 100644 --- a/machine.go +++ b/machine.go @@ -4,27 +4,245 @@ import ( "errors" ) +type MachineState interface { + isDone() bool +} + +type MachineContext interface{} + +type Value interface{} + +type Return struct { + ctx MachineContext + value Value +} + +func (r Return) isDone() bool { + return false +} + +type Env []Value + +type Compute struct { + ctx MachineContext + env Env + term Term[NamedDeBruijn] +} + +func (c Compute) isDone() bool { + return false +} + +type Done struct { + term Term[NamedDeBruijn] +} + +func (d Done) isDone() bool { + return true +} + +type FrameAwaitArg struct { + value Value + ctx MachineContext +} + +type FrameAwaitFunTerm struct { + env Env + term Term[NamedDeBruijn] + ctx MachineContext +} + +type FrameAwaitFunValue struct { + value Value + ctx MachineContext +} + +type FrameForce struct{ ctx MachineContext } + +type FrameConstr struct { + env Env + tag uint64 + fields []Term[NamedDeBruijn] + resolvedFields []Value + ctx MachineContext +} + +type FrameCases struct { + env Env + branches []Term[NamedDeBruijn] + ctx MachineContext +} + +type NoFrame struct{} + +type ExBudget struct { + mem int64 + cpu int64 +} + +func (ex ExBudget) occurrences(n uint32) ExBudget { + return ExBudget{ + mem: ex.mem * int64(n), + cpu: ex.cpu * int64(n), + } +} + +var DefaultExBudget = ExBudget{ + mem: 14000000, + cpu: 10000000000, +} + +type MachineCosts struct { + startup ExBudget + variable ExBudget + constant ExBudget + lambda ExBudget + delay ExBudget + force ExBudget + apply ExBudget + constr ExBudget + ccase ExBudget + /// Just the cost of evaluating a Builtin node not the builtin itself. + builtin ExBudget +} + +func (mc MachineCosts) get(kind StepKind) ExBudget { + switch kind { + case ExConstant: + return mc.constant + case ExVar: + return mc.variable + case ExLambda: + return mc.lambda + case ExDelay: + return mc.delay + case ExForce: + return mc.force + case ExApply: + return mc.apply + case ExBuiltin: + return mc.builtin + case ExConstr: + return mc.constr + case ExCase: + return mc.ccase + default: + panic("invalid step kind") + } +} + +var DefaultMachineCosts = MachineCosts{ + startup: ExBudget{mem: 100, cpu: 100}, + variable: ExBudget{ + mem: 100, + cpu: 23000, + }, + constant: ExBudget{ + mem: 100, + cpu: 23000, + }, + lambda: ExBudget{ + mem: 100, + cpu: 23000, + }, + delay: ExBudget{ + mem: 100, + cpu: 23000, + }, + force: ExBudget{ + mem: 100, + cpu: 23000, + }, + apply: ExBudget{ + mem: 100, + cpu: 23000, + }, + builtin: ExBudget{ + mem: 100, + cpu: 23000, + }, + // Placeholder values + constr: ExBudget{ + mem: 30000000000, + cpu: 30000000000, + }, + ccase: ExBudget{ + mem: 30000000000, + cpu: 30000000000, + }, +} + +type StepKind uint8 + +const ( + ExConstant StepKind = iota + ExVar + ExLambda + ExApply + ExDelay + ExForce + ExBuiltin + ExConstr + ExCase +) + +type CostModel struct { + machineCosts MachineCosts + // builtinCosts map[Builtin]ExBudget +} + +var DefaultCostModel = CostModel{ + machineCosts: DefaultMachineCosts, +} + type Machine struct { - slippage uint32 - unbudgeted_steps [8]uint32 - Logs []string + costs CostModel + slippage uint32 + exBudget ExBudget + unbudgetedSteps [10]uint32 + Logs []string } func CreateMachine(slippage uint32) Machine { return Machine{ + DefaultCostModel, slippage, - [8]uint32{0, 0, 0, 0, 0, 0, 0, 0}, + DefaultExBudget, + [10]uint32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, make([]string, 0), } } -func (m *Machine) Run(term *Term[NamedDeBruijn]) (*Term[NamedDeBruijn], error) { - return nil, errors.New("anything for now") +func (m *Machine) Run(term *Term[NamedDeBruijn]) (Term[NamedDeBruijn], error) { + startupBudget := m.costs.machineCosts.startup + m.spendBudget(startupBudget) + + var state MachineState = Compute{ctx: NoFrame{}, env: make([]Value, 0), term: term} + + var err error + for { + switch state.(type) { + case Compute: + state, err = m.compute() + case Return: + state, err = m.returnCompute() + case Done: + return state.(Done).term, nil + } + + if err != nil { + return nil, err + } + } } -func (m *Machine) compute() {} +func (m *Machine) compute() (MachineState, error) { + return nil, nil +} -func (m *Machine) returnCompute() {} +func (m *Machine) returnCompute() (MachineState, error) { + return nil, nil +} func (m *Machine) forceEvaluate() {} @@ -36,6 +254,32 @@ func (m *Machine) lookupVar() {} func (m *Machine) stepAndMaybeSpend() {} -func (m *Machine) spendUnbudgetedSteps() {} +func (m *Machine) spendUnbudgetedSteps() error { + for i := range m.unbudgetedSteps { + unspent_step_budget := + m.costs.machineCosts.get(StepKind(i)) + + unspent_step_budget.occurrences(m.unbudgetedSteps[i]) + + if err := m.spendBudget(unspent_step_budget); err != nil { + return err + } + + m.unbudgetedSteps[i] = 0 + } + + m.unbudgetedSteps[9] = 0 + + return nil +} -func (m *Machine) spendBudget() {} +func (m *Machine) spendBudget(exBudget ExBudget) error { + m.exBudget.mem -= exBudget.mem + m.exBudget.cpu -= exBudget.cpu + + if m.exBudget.mem < 0 || m.exBudget.cpu < 0 { + return errors.New("out of budget") + } + + return nil +} diff --git a/term.go b/term.go index c8914aa..e70baf9 100644 --- a/term.go +++ b/term.go @@ -66,8 +66,21 @@ type Apply[T Binder] struct { Argument Term[T] } +// (builtin addInteger) type Builtin struct { DefaultFunction } +// (constr 0 (con integer 1) (con string "1234")) +type Constr[T Binder] struct { + Tag uint64 + fields []Term[T] +} + +// (case (constr 0) (constr 1 (con integer 1))) +type Case[T Binder] struct { + Constr Term[T] + Branches []Term[T] +} + type Error struct{} From 26d802e9c5946b455822abe3983a5e07f2ce74be Mon Sep 17 00:00:00 2001 From: rvcas Date: Tue, 5 Sep 2023 22:24:49 -0400 Subject: [PATCH 2/2] fix: occurences should mutate --- machine.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/machine.go b/machine.go index 28ebdbf..2a7aaf4 100644 --- a/machine.go +++ b/machine.go @@ -80,11 +80,9 @@ type ExBudget struct { cpu int64 } -func (ex ExBudget) occurrences(n uint32) ExBudget { - return ExBudget{ - mem: ex.mem * int64(n), - cpu: ex.cpu * int64(n), - } +func (ex *ExBudget) occurrences(n uint32) { + ex.mem *= int64(n) + ex.cpu *= int64(n) } var DefaultExBudget = ExBudget{