ichiban / prolog

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

How to create Compound items #294

Closed vernonr3 closed 1 year ago

vernonr3 commented 1 year ago

I'm wondering how the interpreter internally knows/stores the difference between foo([List1]). and foo([List1],[List2]). ? I'm looking at a potential use case where an external package would want to create complex facts dynamically. Thanks

ichiban commented 1 year ago

Hi! You can generate foo([List1]). and foo([List1],[List2]). in Go like this: https://go.dev/play/p/xEll9GhPhmR

package main

import (
    "os"

    "github.com/ichiban/prolog"
    "github.com/ichiban/prolog/engine"
)

func main() {
    p := prolog.New(nil, os.Stdout)
    p.Register1(engine.NewAtom("create1"), Create1)
    p.Register1(engine.NewAtom("create2"), Create2)
    if err := p.QuerySolution(`create1(X), write(X), nl, create2(Y), write(Y), nl.`).Err(); err != nil {
        panic(err)
    }
}

var atomFoo = engine.NewAtom("foo")

func Create1(vm *engine.VM, out engine.Term, k engine.Cont, env *engine.Env) *engine.Promise {
    return engine.Unify(vm, out, atomFoo.Apply(engine.List(engine.NewVariable())), k, env)
}

func Create2(vm *engine.VM, out engine.Term, k engine.Cont, env *engine.Env) *engine.Promise {
    return engine.Unify(vm, out, atomFoo.Apply(engine.List(engine.NewVariable()), engine.List(engine.NewVariable())), k, env)
}
foo([_65])
foo([_72],[_73])

Program exited.

The difference between foo(X) and foo(X, Y) is the number of arguments to Atom.Apply().

vernonr3 commented 1 year ago

Thanks... that's very helpful...