Beispiel #1
0
func (d *Dwimmer) Answer(q term.T, optionalSetting ...*term.SettingT) (term.T, term.T) {
	var s *term.SettingT
	if len(optionalSetting) == 1 {
		s = optionalSetting[0]
	} else {
		s = term.InitT()
		s.AppendTerm(BuiltinAnswerer.T(q))
	}
	a := dynamics.SubRun(d, q, s)
	switch a.Head() {
	case core.Answer:
		return a.Values()[0], nil
	case core.Yes, core.No:
		return a, nil
	}
	follow := term.InitT()
	isAnswer := dynamics.SubRun(d, IsAnswer.T(a, q), s, follow)
	for {
		switch isAnswer.Head() {
		case core.Yes:
			result, err := d.Answer(WhatAnswer.T(a, q))
			if err != nil {
				return nil, a
			}
			return result, nil
		case core.No:
			return nil, a
		}
		isAnswer = dynamics.SubRun(d, IsAnswerClarify.T(), s, follow)
	}
}
Beispiel #2
0
func RunDefaultInitializers(d dynamics.Dwimmer) {
	s := term.InitT()
	s.AppendTerm(Initialization.T())
	for _, t := range dynamics.DefaultInitializers {
		c := term.InitT()
		dynamics.SubRun(d, t, s, c)
	}
}
Beispiel #3
0
func StartShell(d dynamics.Dwimmer, ts ...term.T) term.T {
	pushShell()
	defer popShell()

	for _, t := range ts {
		shellSetting.AppendTerm(t)
	}

	for {
		transition := ElicitAction(d, term.InitT(), shellSetting.Setting)
		result := transition.Step(d, shellSetting)
		if result != nil {
			return result
		}
	}
}
Beispiel #4
0
func (d *Dwimmer) watchdog(setting *term.SettingT) {
	if rand.Int()%(watchFrequency<<(3*watcherDepth)) == 0 {
		watcherDepth++
		defer func() { watcherDepth-- }()
		parent := setting.Copy().AppendAction(term.MetaC())
		oldWatcher := d.lastWatcher
		newWatcher := term.InitT()
		var Q term.T
		if d.lastWatcher == nil {
			Q = IsAllWell.T(term.MakeChannel(parent))
		} else {
			Q = IsAllWellPred.T(term.MakeChannel(parent), term.MakeChannel(oldWatcher))
		}
		d.lastWatcher = newWatcher
		dynamics.SubRun(d, Q, parent, newWatcher)
	}
}
Beispiel #5
0
func SubRun(d Dwimmer, Q term.T, parent *term.SettingT, optionalChild ...*term.SettingT) term.T {
	var child *term.SettingT
	if len(optionalChild) == 1 {
		child = optionalChild[0]
	} else {
		child = term.InitT()
	}
	child.AppendTerm(Parent(parent))
	child.AppendTerm(Q)
	d.Push(Q)
	stackCheck()
	A := d.Run(child)
	parent.AppendTerm(OpenChannel.T(term.MakeChannel(child)))
	if A != nil {
		parent.AppendTerm(A)
	}
	d.Pop()
	return A
}
Beispiel #6
0
func TestRepresentations(t *testing.T) {
	d := dwimmer.TestDwimmer()
	defer d.Close()
	template := term.Make("term with argument [] and second half here")
	template2, err := represent.ToTemplate(d, represent.Template(template))
	if err != nil {
		t.Errorf("received error %v", err)
	}
	if template != template2 {
		t.Errorf("%v != %v", template, template2)
	}
	setting := term.Init().Append(template)
	setting2, err := represent.ToSetting(d, represent.Setting(setting))
	if err != nil {
		t.Errorf("received error %v", err)
	}
	if term.IDSetting(setting) != term.IDSetting(setting2) {
		t.Errorf("%v != %v", setting, setting2)
	}
	actions := []term.ActionC{term.ReturnC(term.Cr(3)), term.ClarifyC(term.Cr(2), core.OK.C()), term.DeleteC(7)}
	for _, action := range actions {
		action2, err := represent.ToActionC(d, represent.ActionC(action))
		if err != nil {
			t.Errorf("received error %v", err)
		}
		if term.IDActionC(action) != term.IDActionC(action2) {
			t.Errorf("%v != %v", action, action2)
		}
	}
	stub := term.Make("stub")
	tm := template.T(stub.T())
	tm2, err := represent.ToT(d, represent.T(tm))
	if err != nil {
		t.Errorf("received error %v", err)
	}
	if tm2.String() != tm.String() {
		t.Errorf("%v != %v", tm2, tm)
	}
	rep, err := d.Answer(represent.Explicit.T(represent.T(tm)))
	if err != nil {
		t.Errorf("failed to make representation explicit: %v", err)
	}
	tm3, err := represent.ToT(d, rep)
	if err != nil {
		t.Errorf("received error %v", err)
	}
	if tm3.String() != tm.String() {
		t.Errorf("%v != %v", tm3, tm)
	}
	settingT := term.InitT().AppendTerm(tm)
	settingT2, err := represent.ToSettingT(d, represent.SettingT(settingT))
	if err != nil {
		t.Errorf("received error %v")
	}
	if settingT2.Setting.ID != settingT.Setting.ID {
		t.Errorf("%v != %v", settingT2, settingT)
	}

	n := -127
	n2, err := represent.ToInt(d, represent.Int(n))
	if err != nil {
		t.Errorf("received error %v", err)
	}
	if n != n2 {
		t.Errorf("%v != %v", n, n2)
	}

	s := "hello ₳"
	s2, err := represent.ToStr(d, represent.Str(s))
	if err != nil {
		t.Errorf("received error %v", err)
	}
	if s != s2 {
		t.Errorf("%s != %s", s, s2)
	}
}
Beispiel #7
0
func (d *Dwimmer) Do(a term.ActionT, s *term.SettingT) term.T {
	switch a.Act {
	case term.Return:
		return a.Args[0]
	case term.Ask:
		Q := a.Args[0]
		child := term.InitT()
		dynamics.SubRun(d, Q, s, child)
		return nil
	case term.View:
		value := a.Args[0]
		if value != nil {
			s.AppendTerm(value)
		} else {
			s.AppendTerm(Closed.T())
		}
		return nil
	case term.Replace:
		//value := a.Args[0]
		//n := a.IntArgs[0]
		//s.Rollback(n).AppendTerm(value)
		return nil
	case term.Replay:
		n := a.IntArgs[0]
		s.Rollback(n)
		return nil
	case term.Clarify:
		Q := a.Args[1]
		//TODO handle null pointers much better...
		//(e.g. one part of an expression may refer to a deleted variable)
		if a.Args[0] == nil {
			s.AppendTerm(Closed.T())
			return nil
		}
		var target *term.SettingT
		channel, err := represent.ToChannel(d, a.Args[0])
		if err == nil {
			target = channel.(term.Channel).Instantiate()
		} else {
			var othererr term.T
			target, othererr = represent.ToSettingT(d, a.Args[0])
			if othererr != nil {
				s.AppendTerm(NotAChannel.T(err))
				return nil
			}
		}
		dynamics.SubRun(d, Q, s, target)
		return nil
	case term.Correct:
		n := a.IntArgs[0]
		old := s.Setting.Rollback(n)
		transition := ElicitAction(d, term.InitT(), old)
		d.Save(old, transition)
		s.AppendTerm(core.OK.T())
		return nil
	case term.Delete:
		n := a.IntArgs[0]
		s.Args[n] = nil
		s.AppendTerm(core.OK.T())
		return nil
	case term.Meta:
		s.AppendTerm(CurrentSetting.T(represent.SettingT(s)))
		return nil
	}
	panic("unknown kind of action")
}
Beispiel #8
0
func (d *Dwimmer) Ask(Q term.T) (term.T, *term.SettingT) {
	setting := term.InitT().AppendTerm(Q)
	return d.Run(setting), setting
}
Beispiel #9
0
package dwimmer

import (
	"github.com/paulfchristiano/dwimmer/dynamics"
	"github.com/paulfchristiano/dwimmer/term"
)

var (
	RunShell     = term.Make("run a shell with prompt [], and reply with the user's return value")
	shellSetting = term.InitT().AppendTerm(term.Make("[Home]").T())
	oldShells    []*term.SettingT
)

func startWithPrompt(d dynamics.Dwimmer, setting *term.SettingT, question term.T) term.T {
	return StartShell(d, dynamics.Parent(setting), question)
}

func pushShell() {
	oldShells = append(oldShells, shellSetting.Copy())
}

func popShell() {
	shellSetting = oldShells[len(oldShells)-1]
	oldShells = oldShells[:len(oldShells)-1]
}

func Show(t term.T) {
	shellSetting.AppendTerm(t)
}

func StartShell(d dynamics.Dwimmer, ts ...term.T) term.T {