mndrix / golog

Prolog interpreter in Go
MIT License
374 stars 39 forks source link

Tighter code intergration with golang #16

Closed lingnand closed 9 years ago

lingnand commented 9 years ago

The idea of having a Prolog-like reference engine in go is brilliant, however I feel that the balance is tilted too much towards the Prolog end. Since the package mainly serves programs in Go, it would actually make more sense to design the interface and APIs more in the way of Go rather than that of Prolog.

Currently I'm building up callables in ways like this:

func NewRule(fact t.Term, conditions ...t.Term) t.Callable {
    // build the comma separated callable list
    cond := conditions[0]
    if len(conditions) > 1 {
        for _, c := range conditions[1:] {
            cond = t.NewCallable(",", cond, c)
        }
    }
    return t.NewCallable(":-", fact, cond)
}

As you can see this is really awkward. I understand the package is intended to be used by feeding in straight strings written in Prolog, but there is no reason why the underlying API couldn't be restructured to fit a more programmatic approach - that will not only allow the Go language to be used more to its advantage, but also saves the cost of parsing. This would be especially meaningful if one is to build a reference engine of relatively big size.

Some problems will lend themselves to easier solutions if this consideration is taken into account. For example, on the issues of atom representation #14, one can simply allow the user to define custom inherit types of Atom that doesn't contain anything if the user wants to save space. One can even imagine the whole system being opened up for more complicated unification processes - the user can define more custom variables and terms and tailor the unification process however they want.

The implementation of relating different functors to their respective functions inside Go feels a bit awkward to me as well. Currently one has to call registerForeign, and throws away a first class function instead to use a token identity for its representation. If we de-couple parsing from reference-working completely, we can just use the function value inside the engine - the user will then use the same function inside Assertz. This is more reader-friendly, and again, more efficient.

All in all, what I'm suggesting is to separate the syntax and logic of Prolog - the logic (mainly unification) should open itself up to suit more programming needs of Go programmers, while the syntax can be any form one would like - be it Go, or Prolog.

mndrix commented 9 years ago

the balance is tilted too much towards the Prolog end

Golog is intended as a Prolog implementation written in Go. Using it as a logic engine for Go is a nice side effect, but not the main focus.

Having said that, I'll certainly consider pull requests that give us something concrete to discuss. Your ideas may be a nice fit for Golog.

You might also be interested in a miniKanren implementation for Go. The end result is quite close to what you describe.

lingnand commented 9 years ago

Thanks for your clarification. Your recommended project is really interesting as well - I think that might be what I'll be using for the moment then