ichiban / prolog

The only reasonable scripting engine for Go.
MIT License
564 stars 27 forks source link

get interpreter for QuerySolution in Go function #317

Closed flashpixx closed 3 months ago

flashpixx commented 3 months ago

Hello, how can I get the interpreter.QuerySolution call within the Go function func(_ *engine.VM, t engine.Term, k engine.Cont, env *engine.Env) *engine.Promise?

I would like to add new facts within the Go function, so I would like to call assertz(......) with my term.

ichiban commented 3 months ago

Hi, the most straightforward way to incorporate assertz/1 with your Go predicate is to output terms from your predicate and feed them to assertz/1 like foo(In, Out), assertz(Out).

Also, you can call engine.Assertz() directly within your Go predicate. It'll be something like:

if _, err := engine.Assertz(vm, engine.NewAtom("foo").Apply(engine.CharList("bar")), engine.Success, env).Force(context.Background()); err != nil {
    return engine.Error(err)
}

I don't think you need to access the interpreter from a Go predicate but if you really need to, you can use closure:

p := prolog.New(nil, nil)
p.Register0(engine.NewAtom("foo"), func(_ *engine.VM, k engine.Cont, env *engine.Env) *engine.Promise {
    if err := p.QuerySolution(`true.`).Err(); err != nil {
        return engine.Error(err)
    }
    return k(env)
}
flashpixx commented 3 months ago

ah okay, so i use the "normal" interpreter, thanks