From e5ef0db1b8dd6be3cb0cf80074b6c1eb988cd510 Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Mon, 4 Mar 2024 10:59:59 -0500 Subject: [PATCH] Use pointers in run options so we can tell what's been set --- actr/model.go | 6 +++--- framework/ccm_pyactr/ccm_pyactr.go | 12 ++++++------ framework/pyactr/pyactr.go | 6 +++--- framework/vanilla_actr/vanilla_actr.go | 4 ++-- modes/web/model.go | 15 +++++++++++---- util/runoptions/errors.go | 15 +++++++++++++-- util/runoptions/runoptions.go | 11 +++++++---- 7 files changed, 45 insertions(+), 24 deletions(-) diff --git a/actr/model.go b/actr/model.go index a2be862..f0bf427 100644 --- a/actr/model.go +++ b/actr/model.go @@ -295,15 +295,15 @@ func (model *Model) SetParam(kv *keyvalue.KeyValue) (err error) { switch kv.Key { case "log_level": - model.DefaultParams.LogLevel = runoptions.ACTRLogLevel(*value.Str) + logLevel := runoptions.ACTRLogLevel(*value.Str) // already validated + model.DefaultParams.LogLevel = &logLevel case "trace_activations": boolVal, _ := value.AsBool() // already validated - model.DefaultParams.TraceActivations = boolVal + model.DefaultParams.TraceActivations = &boolVal case "random_seed": seed := uint32(*value.Number) - model.DefaultParams.RandomSeed = &seed default: diff --git a/framework/ccm_pyactr/ccm_pyactr.go b/framework/ccm_pyactr/ccm_pyactr.go index a1142c0..d51f5b2 100644 --- a/framework/ccm_pyactr/ccm_pyactr.go +++ b/framework/ccm_pyactr/ccm_pyactr.go @@ -148,7 +148,7 @@ func (c *CCMPyACTR) WriteModel(path string, options *runoptions.Options) (output } // If our model is tracing activations, then write out our support file - if options.TraceActivations { + if *options.TraceActivations { err = framework.WriteSupportFile(path, gactarActivateTraceFileName, gactarActivateTraceFile) if err != nil { return @@ -238,7 +238,7 @@ func (c *CCMPyACTR) GenerateCode(options *runoptions.Options) (code []byte, err c.Writeln(" %s = Memory(%s)", memory.ModuleName(), memory.BufferName()) } - if options.TraceActivations { + if *options.TraceActivations { c.Writeln(" trace = ActivateTrace(%s)", memory.ModuleName()) } @@ -287,7 +287,7 @@ func (c *CCMPyACTR) GenerateCode(options *runoptions.Options) (code []byte, err c.Writeln("") } - if options.LogLevel == "info" { + if *options.LogLevel == "info" { // this turns on some logging at the high level c.Writeln(" def __init__(self):") c.Writeln(" super().__init__(log=True)") @@ -380,7 +380,7 @@ func (c CCMPyACTR) writeImports(runOptions *runoptions.Options) { c.Write("from python_actr import %s\n", strings.Join(additionalImports, ", ")) } - if runOptions.LogLevel == "detail" { + if *runOptions.LogLevel == "detail" { c.Writeln("from python_actr import log, log_everything") } @@ -389,7 +389,7 @@ func (c CCMPyACTR) writeImports(runOptions *runoptions.Options) { c.Writeln(fmt.Sprintf("from %s import CCMPrint", ccmPrintImportName)) } - if runOptions.TraceActivations { + if *runOptions.TraceActivations { c.Writeln("") c.Writeln(fmt.Sprintf("from %s import ActivateTrace", gactarActivateTraceImportName)) } @@ -494,7 +494,7 @@ func (c CCMPyACTR) writeMain(runOptions *runoptions.Options) { c.Writeln("if __name__ == \"__main__\":") c.Writeln(fmt.Sprintf(" model = %s()", c.className)) - if runOptions.LogLevel == "detail" { + if *runOptions.LogLevel == "detail" { c.Writeln(" log(summary=1)") c.Writeln(" log_everything(model)") } diff --git a/framework/pyactr/pyactr.go b/framework/pyactr/pyactr.go index f8f0bcd..ba960e3 100644 --- a/framework/pyactr/pyactr.go +++ b/framework/pyactr/pyactr.go @@ -254,7 +254,7 @@ func (p *PyACTR) GenerateCode(options *runoptions.Options) (code []byte, err err p.Writeln(" rule_firing=%s,", numbers.Float64Str(*procedural.DefaultActionTime)) } - if options.TraceActivations { + if *options.TraceActivations { p.Writeln(" activation_trace=True,") } @@ -498,14 +498,14 @@ func (p PyACTR) writeMain(runOptions *runoptions.Options) { options := []string{"gui=False"} - if runOptions.LogLevel == "min" { + if *runOptions.LogLevel == "min" { options = append(options, "trace=False") } p.Writeln(" sim = %s.simulation( %s )", p.className, strings.Join(options, ", ")) p.Writeln(" sim.run()") - if runOptions.LogLevel != "min" { + if *runOptions.LogLevel != "min" { p.Writeln(" if goal.test_buffer('full'):") p.Writeln(" print('chunk left in goal: ' + str(goal.pop()))") p.Writeln(" if %s.retrieval.test_buffer('full'):", p.className) diff --git a/framework/vanilla_actr/vanilla_actr.go b/framework/vanilla_actr/vanilla_actr.go index 77c6305..d1912bf 100644 --- a/framework/vanilla_actr/vanilla_actr.go +++ b/framework/vanilla_actr/vanilla_actr.go @@ -243,7 +243,7 @@ func (v *VanillaACTR) GenerateCode(options *runoptions.Options) (code []byte, er v.Writeln("\t:dat %s", numbers.Float64Str(*procedural.DefaultActionTime)) } - switch options.LogLevel { + switch *options.LogLevel { case "min": v.Writeln("\t:trace-detail low") case "info": @@ -252,7 +252,7 @@ func (v *VanillaACTR) GenerateCode(options *runoptions.Options) (code []byte, er v.Writeln("\t:trace-detail high") } - if options.TraceActivations { + if *options.TraceActivations { v.Writeln("\t:act t") } diff --git a/modes/web/model.go b/modes/web/model.go index b1454fd..fae1f05 100644 --- a/modes/web/model.go +++ b/modes/web/model.go @@ -103,16 +103,23 @@ func (w Web) actrOptionsFromJSON(defaults *runoptions.Options, options *runOptio opts.Frameworks = options.Frameworks if options.LogLevel != nil { - opts.LogLevel = runoptions.ACTRLogLevel(*options.LogLevel) + if !runoptions.ValidLogLevel(*options.LogLevel) { + err = runoptions.ErrInvalidLogLevel{Level: *options.LogLevel} + } else { + logLevel := runoptions.ACTRLogLevel(*options.LogLevel) + opts.LogLevel = &logLevel + } } if options.TraceActivations != nil { - opts.TraceActivations = *options.TraceActivations + opts.TraceActivations = options.TraceActivations } - opts.RandomSeed = options.RandomSeed + if options.RandomSeed != nil { + opts.RandomSeed = options.RandomSeed + } - return &opts, nil + return &opts, err } func generateModel(amodFile string) (model *actr.Model, err error) { diff --git a/util/runoptions/errors.go b/util/runoptions/errors.go index 550c02a..20a3c16 100644 --- a/util/runoptions/errors.go +++ b/util/runoptions/errors.go @@ -1,6 +1,9 @@ package runoptions -import "fmt" +import ( + "fmt" + "strings" +) type ErrFrameworkNotActive struct { Name string @@ -15,5 +18,13 @@ type ErrInvalidFrameworkName struct { } func (e ErrInvalidFrameworkName) Error() string { - return fmt.Sprintf("invalid framework name: %q", e.Name) + return fmt.Sprintf("invalid framework name: %q; expected one of %q", e.Name, strings.Join(ValidFrameworks, ", ")) +} + +type ErrInvalidLogLevel struct { + Level string +} + +func (e ErrInvalidLogLevel) Error() string { + return fmt.Sprintf("invalid log level: %q; expected one of %q", e.Level, strings.Join(ACTRLoggingLevels, ", ")) } diff --git a/util/runoptions/runoptions.go b/util/runoptions/runoptions.go index 3a2b5d4..a1a5d8b 100644 --- a/util/runoptions/runoptions.go +++ b/util/runoptions/runoptions.go @@ -45,10 +45,10 @@ type Options struct { InitialBuffers InitialBuffers // One of 'min', 'info', or 'detail' - LogLevel ACTRLogLevel + LogLevel *ACTRLogLevel // If true, output detailed info about activations - TraceActivations bool + TraceActivations *bool // The seed to use for generating pseudo-random numbers (allows for reproducible runs) // For all frameworks, if it is not set it uses current system time. @@ -58,10 +58,13 @@ type Options struct { // New returns a default-initialized Options struct. func New() Options { + logLevel := ACTRLogLevel("info") + activations := false + return Options{ Frameworks: FrameworkNameList{"all"}, - LogLevel: ACTRLogLevel("info"), - TraceActivations: false, + LogLevel: &logLevel, + TraceActivations: &activations, RandomSeed: nil, } }