Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Machine run and some budget methods #3

Merged
merged 2 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 252 additions & 10 deletions machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,243 @@
"errors"
)

type MachineState interface {
isDone() bool
}

type MachineContext interface{}

type Value interface{}

type Return struct {
ctx MachineContext

Check failure on line 16 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

field `ctx` is unused (unused)
value Value

Check failure on line 17 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

field `value` is unused (unused)
}

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

Check failure on line 45 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

field `value` is unused (unused)
ctx MachineContext

Check failure on line 46 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

field `ctx` is unused (unused)
}

type FrameAwaitFunTerm struct {
env Env

Check failure on line 50 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

field `env` is unused (unused)
term Term[NamedDeBruijn]

Check failure on line 51 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

field `term` is unused (unused)
ctx MachineContext

Check failure on line 52 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

field `ctx` is unused (unused)
}

type FrameAwaitFunValue struct {
value Value

Check failure on line 56 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

field `value` is unused (unused)
ctx MachineContext
}

type FrameForce struct{ ctx MachineContext }

type FrameConstr struct {
env Env

Check failure on line 63 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

field `env` is unused (unused)
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) {
ex.mem *= int64(n)
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)

Check failure on line 216 in machine.go

View workflow job for this annotation

GitHub Actions / lint (1.20.x, ubuntu-latest)

Error return value of `m.spendBudget` is not checked (errcheck)

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() {}

Expand All @@ -36,6 +252,32 @@

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
}
13 changes: 13 additions & 0 deletions term.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Loading