Documentation ¶
Index ¶
- Variables
- type Interpreter
- func (i *Interpreter) Exec(query string, args ...interface{}) error
- func (i *Interpreter) ExecContext(ctx context.Context, query string, args ...interface{}) error
- func (i *Interpreter) Query(query string, args ...interface{}) (*Solutions, error)
- func (i *Interpreter) QueryContext(ctx context.Context, query string, args ...interface{}) (*Solutions, error)
- func (i *Interpreter) QuerySolution(query string, args ...interface{}) *Solution
- func (i *Interpreter) QuerySolutionContext(ctx context.Context, query string, args ...interface{}) *Solution
- type Scanner
- type Solution
- type Solutions
- type TermString
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrClosed = errors.New("closed")
ErrClosed indicates the Solutions are already closed and unable to perform the operation.
var ErrNoSolutions = errors.New("no solutions")
ErrNoSolutions indicates there's no solutions for the query.
Functions ¶
This section is empty.
Types ¶
type Interpreter ¶ added in v0.2.0
Interpreter is a Prolog interpreter. The zero value is a valid interpreter without any predicates/operators defined.
func New ¶ added in v0.2.0
func New(in io.Reader, out io.Writer) *Interpreter
New creates a new Prolog interpreter with predefined predicates/operators.
Example (AcyclicTerm) ¶
p := New(nil, nil) sols, _ := p.Query(`acyclic_term(a(1, _)).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`X = f(X), acyclic_term(X).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close()
Output: true false
Example (Arg) ¶
p := New(nil, nil) sols, _ := p.Query(`arg(1, foo(a, b), a).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`arg(1, foo(a, b), X).`) for sols.Next() { var s struct { X string } _ = sols.Scan(&s) fmt.Printf("X = %s\n", s.X) } _ = sols.Close() sols, _ = p.Query(`arg(1, foo(X, b), a).`) for sols.Next() { var s struct { X string } _ = sols.Scan(&s) fmt.Printf("X = %s\n", s.X) } _ = sols.Close() sols, _ = p.Query(`arg(1, foo(X, b), Y), X = a.`) for sols.Next() { var s struct { X, Y string } _ = sols.Scan(&s) fmt.Printf("X = %s, Y = %s\n", s.X, s.Y) } _ = sols.Close() sols, _ = p.Query(`arg(1, foo(a, b), b).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`arg(0, foo(a, b), foo).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`arg(3, foo(a, b), N).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`arg(X, foo(a, b), a).`) sols.Next() fmt.Printf("%v\n", sols.Err()) _ = sols.Close() sols, _ = p.Query(`arg(1, X, a).`) sols.Next() fmt.Printf("%v\n", sols.Err()) _ = sols.Close() sols, _ = p.Query(`arg(0, atom, A).`) sols.Next() fmt.Printf("%v\n", sols.Err()) _ = sols.Close() sols, _ = p.Query(`arg(0, 3, A).`) sols.Next() fmt.Printf("%v\n", sols.Err()) _ = sols.Close()
Output: true X = a X = a X = a, Y = a false false false error(instantiation_error,arg/3) error(instantiation_error,arg/3) error(type_error(compound,atom),arg/3) error(type_error(compound,3),arg/3)
Example (Callable) ¶
p := New(nil, nil) sols, _ := p.Query(`callable(a).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`callable(3).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`callable(X).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`callable((1,2)).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close()
Output: true false false true
Example (Ground) ¶
p := New(nil, nil) sols, _ := p.Query(`ground(3).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`ground(a(1, _)).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close()
Output: true false
Example (Phrase) ¶
p := New(nil, nil) _ = p.Exec(` determiner --> [the]. determiner --> [a]. noun --> [boy]. noun --> [girl]. verb --> [likes]. verb --> [scares]. noun_phrase --> determiner, noun. noun_phrase --> noun. verb_phrase --> verb. verb_phrase --> verb, noun_phrase. sentence --> noun_phrase, verb_phrase. `) sols, _ := p.Query(`phrase([the], [the]).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`phrase(sentence, [the, girl, likes, the, boy]).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`phrase(sentence, [the, girl, likes, the, boy, today]).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`phrase(sentence, [the, girl, likes]).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`phrase(sentence, Sentence).`) for sols.Next() { var s struct { Sentence []string } _ = sols.Scan(&s) fmt.Printf("Sentence = %s\n", s.Sentence) break // Many other sentences follow. } _ = sols.Close() sols, _ = p.Query(`phrase(noun_phrase, [the, girl, scares, the, boy], Rest).`) for sols.Next() { var s struct { Rest []string } _ = sols.Scan(&s) fmt.Printf("Rest = %s\n", s.Rest) } _ = sols.Close()
Output: true true false true Sentence = [the boy likes] Rest = [scares the boy]
Example (Sort) ¶
p := New(nil, nil) sols, _ := p.Query(`sort([1, 1], Sorted).`) for sols.Next() { var s struct { Sorted []int } _ = sols.Scan(&s) fmt.Printf("Sorted = %d\n", s.Sorted) } _ = sols.Close() sols, _ = p.Query(`sort([X, 1], [1, 1]).`) for sols.Next() { var s struct { X int } _ = sols.Scan(&s) fmt.Printf("X = %d\n", s.X) } _ = sols.Close() sols, _ = p.Query(`sort([1, 1], [1, 1]).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`sort([V], V).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`sort([f(U),U,U,f(V),f(U),V],L).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close()
Output: Sorted = [1] X = 1 false true true
Example (Subsumes_term) ¶
p := New(nil, nil) sols, _ := p.Query(`subsumes_term(a, a).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`subsumes_term(f(X,Y), f(Z,Z)).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`subsumes_term(f(Z,Z), f(X,Y)).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`subsumes_term(g(X), g(f(X))).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`subsumes_term(X, f(X)).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close() sols, _ = p.Query(`subsumes_term(X, Y), subsumes_term(Y, f(X)).`) fmt.Printf("%t\n", sols.Next()) _ = sols.Close()
Output: true true false false false true
func (*Interpreter) Exec ¶ added in v0.2.0
func (i *Interpreter) Exec(query string, args ...interface{}) error
Exec executes a prolog program.
Example (Placeholders) ¶
p := New(nil, os.Stdout) _ = p.Exec(`my_atom(?).`, "foo") sols, _ := p.Query(`my_atom(A), atom(A), write(A), nl.`) sols.Next() _ = sols.Close() _ = p.Exec(`my_int(?, ?, ?, ?, ?).`, int8(1), int16(1), int32(1), int64(1), 1) sols, _ = p.Query(`my_int(I, I, I, I, I), integer(I), write(I), nl.`) sols.Next() _ = sols.Close() _ = p.Exec(`my_float(?, ?).`, float32(1), float64(1)) sols, _ = p.Query(`my_float(F, F), float(F), write(F), nl.`) sols.Next() _ = sols.Close() _ = p.Exec(`my_atom_list(?).`, []string{"foo", "bar", "baz"}) sols, _ = p.Query(`my_atom_list(As), maplist(atom, As), write(As), nl.`) sols.Next() _ = sols.Close() _ = p.Exec(`my_int_list(?).`, []int{1, 2, 3}) sols, _ = p.Query(`my_int_list(Is), maplist(integer, Is), write(Is), nl.`) sols.Next() _ = sols.Close() _ = p.Exec(`my_float_list(?).`, []float64{1, 2, 3}) sols, _ = p.Query(`my_float_list(Fs), maplist(float, Fs), write(Fs), nl.`) sols.Next() _ = sols.Close()
Output: foo 1 1.0 [foo,bar,baz] [1,2,3] [1.0,2.0,3.0]
func (*Interpreter) ExecContext ¶ added in v0.3.0
func (i *Interpreter) ExecContext(ctx context.Context, query string, args ...interface{}) error
ExecContext executes a prolog program with context.
func (*Interpreter) Query ¶ added in v0.2.0
func (i *Interpreter) Query(query string, args ...interface{}) (*Solutions, error)
Query executes a prolog query and returns *Solutions.
Example (Placeholders) ¶
p := New(nil, os.Stdout) sols, _ := p.Query(`A = ?, atom(A), write(A), nl.`, "foo") sols.Next() _ = sols.Close() sols, _ = p.Query(`(I, I, I, I, I) = (?, ?, ?, ?, ?), integer(I), write(I), nl.`, int8(1), int16(1), int32(1), int64(1), 1) sols.Next() _ = sols.Close() sols, _ = p.Query(`(F, F) = (?, ?), float(F), write(F), nl.`, float32(1), float64(1)) sols.Next() _ = sols.Close() sols, _ = p.Query(`L = ?, maplist(atom, L), write(L), nl.`, []string{"foo", "bar", "baz"}) sols.Next() _ = sols.Close() sols, _ = p.Query(`L = ?, maplist(integer, L), write(L), nl.`, []int{1, 2, 3}) sols.Next() _ = sols.Close() sols, _ = p.Query(`L = ?, maplist(float, L), write(L), nl.`, []float64{1, 2, 3}) sols.Next() _ = sols.Close()
Output: foo 1 1.0 [foo,bar,baz] [1,2,3] [1.0,2.0,3.0]
func (*Interpreter) QueryContext ¶ added in v0.3.0
func (i *Interpreter) QueryContext(ctx context.Context, query string, args ...interface{}) (*Solutions, error)
QueryContext executes a prolog query and returns *Solutions with context.
func (*Interpreter) QuerySolution ¶ added in v0.6.0
func (i *Interpreter) QuerySolution(query string, args ...interface{}) *Solution
QuerySolution executes a Prolog query for the first solution.
func (*Interpreter) QuerySolutionContext ¶ added in v0.6.0
func (i *Interpreter) QuerySolutionContext(ctx context.Context, query string, args ...interface{}) *Solution
QuerySolutionContext executes a Prolog query with context.
type Scanner ¶ added in v0.15.0
Scanner is an interface for custom conversion from term to Go value.
type Solution ¶ added in v0.6.0
type Solution struct {
// contains filtered or unexported fields
}
Solution is the single result of a query.
type Solutions ¶ added in v0.2.0
type Solutions struct {
// contains filtered or unexported fields
}
Solutions is the result of a query. Everytime the Next method is called, it searches for the next solution. By calling the Scan method, you can retrieve the content of the solution.
func (*Solutions) Close ¶ added in v0.2.0
Close closes the Solutions and terminates the search for other solutions.
func (*Solutions) Next ¶ added in v0.2.0
Next prepares the next solution for reading with the Scan method. It returns true if it finds another solution, or false if there's no further solutions or if there's an error.
func (*Solutions) Scan ¶ added in v0.2.0
Scan copies the variable values of the current solution into the specified struct/map.
Example ¶
p := New(nil, nil) sols, _ := p.Query(`A = foo, I = 42, F = 3.14.`) for sols.Next() { var s struct { A string I int F float64 } _ = sols.Scan(&s) fmt.Printf("A = %s\n", s.A) fmt.Printf("I = %d\n", s.I) fmt.Printf("F = %.2f\n", s.F) }
Output: A = foo I = 42 F = 3.14
Example (List) ¶
p := New(nil, nil) sols, _ := p.Query(`Atoms = [foo, bar], Integers = [1, 2], Floats = [1.1, 2.1], Mixed = [foo, 1, 1.1].`) for sols.Next() { var s struct { Atoms []string Integers []int64 Floats []float64 Mixed []interface{} } _ = sols.Scan(&s) fmt.Printf("Atoms = %s\n", s.Atoms) fmt.Printf("Integers = %d\n", s.Integers) fmt.Printf("Floats = %.1f\n", s.Floats) fmt.Printf("Mixed = %v\n", s.Mixed) }
Output: Atoms = [foo bar] Integers = [1 2] Floats = [1.1 2.1] Mixed = [foo 1 1.1]
Example (Tag) ¶
p := New(nil, nil) sols, _ := p.Query(`A = foo, I = 42, F = 3.14.`) for sols.Next() { var s struct { Atom string `prolog:"A"` Integer int `prolog:"I"` Float float64 `prolog:"F"` } _ = sols.Scan(&s) fmt.Printf("Atom = %s\n", s.Atom) fmt.Printf("Integer = %d\n", s.Integer) fmt.Printf("Float = %.2f\n", s.Float) }
Output: Atom = foo Integer = 42 Float = 3.14