//TODO the algorithms part could be more efficient, but I don't really care func analogies(d dynamics.Dwimmer, s *term.Setting, n int) ([]*term.Setting, []float32) { if s.Size == 1 { return contenders(d, s.Last, n) } previousSetting := s.Previous lastLine := s.Last previousAnalogies, previousPriorities := analogies(d, previousSetting, n+1) possibilities, possiblePriorities := []*term.Setting{}, new(indexHeap) i := 0 for j, priority := range previousPriorities { analogy := previousAnalogies[j] for _, setting := range d.Continuations(analogy) { fit, canMatch := match(setting.Last, lastLine) if canMatch { possiblePriorities.Push(prioritized{ index: i, priority: priority * fit, }) i++ possibilities = append(possibilities, setting) } } } heap.Init(possiblePriorities) result := make([]*term.Setting, 0) priorities := make([]float32, 0) for i := 0; i < n && possiblePriorities.Len() > 0; i++ { next := heap.Pop(possiblePriorities).(prioritized) priorities = append(priorities, next.priority) result = append(result, possibilities[next.index]) } return result, priorities }
func getInput(d dynamics.Dwimmer, context *term.SettingT, hintstrings, toolmap term.T) term.T { quotedHints, err := represent.ToList(d, hintstrings) if err != nil { return represent.ConversionError.T(hintstrings, err) } hints := make([]string, len(quotedHints)) for i, quoted := range quotedHints { hints[i], err = represent.ToStr(d, quoted) if err != nil { return represent.ConversionError.T(quoted, err) } } tools := make(map[rune]string) for toolmap.Head() != maps.Empty { switch toolmap.Head() { case maps.Cons: vs := toolmap.Values() c, err := represent.ToRune(d, vs[0]) if err != nil { return represent.ConversionError.T(vs[0], err) } s, err := represent.ToStr(d, vs[1]) if err != nil { return represent.ConversionError.T(vs[1], err) } tools[c] = s toolmap = vs[2] default: context.AppendTerm(UnrecognizedDictionary.T()) return nil } } input := d.Readln(" < ", hints, tools) return core.Answer.T(represent.Str(input)) }
func run(d dynamics.Dwimmer, s *term.SettingT, quotedSetting term.T) term.T { setting, err := represent.ToSettingT(d, quotedSetting) if err != nil { return represent.ConversionError.T(quotedSetting, err) } result := d.Run(setting) if result == nil { return NoOutput.T(represent.SettingT(setting)) } return Result.T(represent.T(result), represent.SettingT(setting)) }
func getTransition(d dynamics.Dwimmer, s *term.SettingT, quotedSetting term.T) term.T { setting, err := represent.ToSetting(d, quotedSetting) if err != nil { return term.Make("asked to get a transition in setting [], "+ "but while converting to a setting received []").T(quotedSetting, err) } result, ok := d.Get(setting) if !ok { return NoCompiledAction.T() } return core.Answer.T(represent.Transition(result)) }
func fallThrough(d dynamics.Dwimmer, s *term.SettingT, quotedSetting term.T) term.T { settingT, err := represent.ToSettingT(d, quotedSetting) if err != nil { return term.Make("asked to decide what to do in setting [], "+ "but while converting to a setting received []").T(quotedSetting, err) } transition := ElicitAction(d, s, settingT.Setting) if shouldSave(transition) { d.Save(settingT.Setting, transition) } return TakeTransition.T(represent.Transition(transition)) }
func allSettings(d dynamics.Dwimmer, s *term.SettingT) term.T { queue := []*term.Setting{term.Init()} for k := 0; k < len(queue); k++ { top := queue[k] queue = append(queue, d.Continuations(top)...) } result := make([]term.T, len(queue)) for i, setting := range queue { result[i] = represent.Setting(setting) } return core.Answer.T(represent.List(result)) }
func getContinuations(d dynamics.Dwimmer, s *term.SettingT, quotedSetting term.T) term.T { setting, err := represent.ToSetting(d, quotedSetting) if err != nil { return term.Make("asked to return the continuations from a setting, " + "but while converting to a setting received []").T(err) } continuations := d.Continuations(setting) result := make([]term.T, len(continuations)) for i, c := range continuations { result[i] = represent.Setting(c) } return core.Answer.T(represent.List(result)) }
func findAction(d dynamics.Dwimmer, s *term.SettingT, quotedSetting term.T) term.T { setting, err := represent.ToSetting(d, quotedSetting) if err != nil { return term.Make("asked to decide what to do in setting [], "+ "but while converting to a setting received []").T(quotedSetting, err) } transition, ok := d.Get(setting) if !ok { transition := ElicitAction(d, s, setting) d.Save(setting, transition) } return core.Answer.T(represent.Transition(transition)) }
func nativeSetCursor(d dynamics.Dwimmer, s *term.SettingT, xt, yt term.T) term.T { x, err := represent.ToInt(d, xt) if err != nil { return term.Make("asked to move cursor, but received [] "+ "while converting coordinate [] to an integer").T(err, xt) } y, err := represent.ToInt(d, yt) if err != nil { return term.Make("asked to move cursor, but received [] "+ "while converting coordinate [] to an integer").T(err, yt) } d.SetCursor(x, y) return core.OK.T() }
func setTransition(d dynamics.Dwimmer, s *term.SettingT, quotedTransition, quotedSetting term.T) term.T { transition, err := represent.ToTransition(d, quotedTransition) if err != nil { return term.Make("asked to set a setting to transition [], "+ "but while converting to a transition received []").T(quotedTransition, err) } setting, err := represent.ToSetting(d, quotedSetting) if err != nil { return term.Make("asked to set a transition in setting [], "+ "but while converting to a setting received []").T(quotedSetting, err) } d.Save(setting, transition) return core.OK.T() }
func displayTemplate(d dynamics.Dwimmer, context *term.SettingT, quotedSetting term.T) term.T { setting, err := represent.ToSetting(d, quotedSetting) if err != nil { return represent.ConversionError.T(quotedSetting, err) } settingS := addNames(setting) ShowSettingS(d, settingS) d.Println("") d.Println("") quotedNames := make([]term.T, len(settingS.Names)) for i, name := range settingS.Names { quotedNames[i] = represent.Str(name) } return Names.T(represent.List(quotedNames)) }
func nativePutChar(d dynamics.Dwimmer, s *term.SettingT, char, xt, yt term.T) term.T { c, err := represent.ToRune(d, char) if err != nil { return term.Make("asked to write character, but received [] " + "while converting to a character").T(err) } x, err := represent.ToInt(d, xt) if err != nil { return term.Make("asked to write character, but received [] "+ "while converting coordinate [] to an integer").T(err, xt) } y, err := represent.ToInt(d, yt) if err != nil { return term.Make("asked to write character, but received [] "+ "while converting coordinate [] to an integer").T(err, yt) } d.SetCursor(x, y) d.PrintCh(c) return core.OK.T() }
func Suggestions(d dynamics.Dwimmer, s *term.Setting, n int) ([]term.ActionC, []float32) { settings, settingPriorities := analogies(d, s, n) result := []term.ActionC{} priorities := []float32{} buildingResult: for i, other := range settings { t, _ := d.Get(other) simple, isSimple := t.(dynamics.SimpleTransition) if isSimple { action := simple.Action for _, otherAction := range result { if action.ID() == otherAction.ID() { continue buildingResult } } result = append(result, action) priorities = append(priorities, settingPriorities[i]) } } return result, priorities }
func ElicitAction(d dynamics.Dwimmer, context *term.SettingT, setting *term.Setting) dynamics.Transition { for { Q := FallThrough.T(represent.Setting(setting)) result := dynamics.SubRun(d, Q, context) switch result.Head() { case TakeTransition: transition, err := represent.ToTransition(d, result.Values()[0]) if err == nil { return transition } case core.OK: default: result, err := d.Answer(TransitionGiven.T(result, Q)) if err == nil { transition, err := represent.ToTransition(d, result) if err == nil { return transition } } } } }
//TODO only do this sometimes, or control better the length, or something... func GetHints(d dynamics.Dwimmer, context *term.SettingT, s *term.SettingS, n int) []string { suggestions, err := d.Answer(similarity.SuggestedActions.T( represent.Setting(s.Setting), represent.Int(n), ), context) if err != nil { return []string{} } suggestionList, err := represent.ToList(d, suggestions) if err != nil { return []string{} } result := []string{} for _, suggestion := range suggestionList { actionC, err := represent.ToActionC(d, suggestion) if err != nil { continue } actionS := actionC.Uninstantiate(s.Names) result = append(result, actionS.String()) } reverseHints(result) return result }
func contenders(d dynamics.Dwimmer, l term.SettingLine, n int) ([]*term.Setting, []float32) { allSettings := d.Continuations(term.Init()) result, priorities := Top(l, allSettings, n) return result, priorities }
func DoC(d dynamics.Dwimmer, a term.ActionC, s *term.SettingT) term.T { return d.Do(a.Instantiate(s.Args), s) }
func setState(d dynamics.Dwimmer, s *term.SettingT, t term.T) term.T { d.SetStorage(t) return core.OK.T() }
func getState(d dynamics.Dwimmer, s *term.SettingT) term.T { return core.Answer.T(d.GetStorage()) }
func ShowSettingS(d dynamics.Dwimmer, settingS *term.SettingS) { d.Clear() for _, line := range settingS.Lines() { d.Println(line) } }
func nativeClear(d dynamics.Dwimmer, s *term.SettingT) term.T { d.Clear() return core.OK.T() }
func OldElicitAction(d dynamics.Dwimmer, context *term.SettingT, subject *term.Setting, hints bool) term.ActionC { settingS := addNames(subject) ShowSettingS(d, settingS) hint_strings := []string{} tool_map := make(map[rune]string) if hints { hint_strings = GetHints(d, context, settingS, 6) tools := similarity.SuggestedTemplates(d, subject, 6) if len(hint_strings) > 0 || len(tools) > 0 { d.Println("") } if len(tools) > 0 { d.Println("") } tips := []rune{'a', 's', 'd', 'w', 'e', 'j'} for i, tool := range tools { tool_map[tips[i]] = tool.String() d.Println(fmt.Sprintf("%c: %v", tips[i], tool)) } if len(hint_strings) > 0 { d.Println("") } for i, hint := range hint_strings { d.Println(fmt.Sprintf("%d. %s", i, hint)) } } d.Println("") for { input := d.Readln(" < ", hint_strings, tool_map) if input == "jump up" { StartShell(d, Interrupted.T(represent.SettingT(context))) } a := parsing.ParseAction(input, settingS.Names) if a == nil { c := parsing.ParseTerm(input, settingS.Names) if c != nil { switch c := c.(type) { case *term.CompoundC: if questionLike(c) { a = new(term.ActionC) *a = term.AskC(c) } case term.ReferenceC: a = new(term.ActionC) *a = term.ViewC(c) } d.Println("please input an action (ask, view, return, close, delete, correct, or tell)") } else { d.Println("that response wasn't parsed correctly") } } if a != nil { for i, n := range a.IntArgs { if n == -1 { a.IntArgs[i] = subject.Size - 1 } } return *a } } }
func nativeSize(d dynamics.Dwimmer, s *term.SettingT) term.T { x, y := d.Size() return WidthHeight.T(represent.Int(x), represent.Int(y)) }