https://github.com/ichiban/prolog Skip to content Sign up * Why GitHub? + Features + Mobile + Actions + Codespaces + Packages + Security + Code review + Issues + Integrations + GitHub Sponsors + Customer stories * Team * Enterprise * Explore + Explore GitHub + Learn and contribute + Topics + Collections + Trending + Learning Lab + Open source guides + Connect with others + The ReadME Project + Events + Community forum + GitHub Education + GitHub Stars program * Marketplace * Pricing + Plans + Compare plans + Contact Sales + Education [ ] * # In this repository All GitHub | Jump to | * No suggested jump to results * # In this repository All GitHub | Jump to | * # In this user All GitHub | Jump to | * # In this repository All GitHub | Jump to | Sign in Sign up {{ message }} ichiban / prolog Public * Notifications * Fork 10 * Star 256 * The only reasonable scripting engine for Go. MIT License 256 stars 10 forks Star Notifications * Code * Issues 1 * Pull requests 2 * Actions * Projects 1 * Wiki * Security * Insights More * Code * Issues * Pull requests * Actions * Projects * Wiki * Security * Insights main Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags 32 branches 13 tags Code Latest commit @ichiban ichiban Merge pull request #142 from ichiban/nth ... d807577 Jan 20, 2022 Merge pull request #142 from ichiban/nth add nth3 d807577 Git stats * 312 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .github/workflows test coverage Nov 28, 2021 cmd/1pl reduce cyclomatic complexity so that gocyclo -over 15 passes Dec 30, 2021 dcg change library interface Dec 11, 2021 docs Set theme jekyll-theme-cayman Dec 12, 2021 engine hide parser options Jan 5, 2022 examples sandboxing example Nov 25, 2021 testdata add some tests Dec 11, 2021 ARCHITECTURE.md simplify packages Nov 23, 2021 LICENSE Create LICENSE Feb 26, 2021 README.md add nth/3 description to README Jan 19, 2022 bootstrap.pl add nth3 Jan 19, 2022 go.mod refactor write option Jan 1, 2022 go.sum refactor write option Jan 1, 2022 interpreter.go add environ/2 Dec 31, 2021 interpreter_test.go Merge pull request #132 from ichiban/query-solution Dec 28, 2021 prolog.gif update README Nov 23, 2021 solutions.go add QuerySolution() Dec 28, 2021 solutions_test.go add some tests Dec 11, 2021 View code [ ] What is this? ichiban/prolog vs otto vs go-lua Getting started Install latest version Usage Instantiate an interpreter Load a Prolog program Run the Prolog program Built-in Predicates License Contributing README.md prolog - the only reasonable scripting engine for Go Go Reference Actions Status Go Report Card codecov Mentioned in Awesome Go What is this? ichiban/prolog is an embeddable scripting language for Go. Unlike any other scripting engines, ichiban/prolog implements logic programming language Prolog. * Easy to reason about: based on first-order logic * Easy to adopt: database/sql-like Go API * Intelligent: full-featured Prolog implementation * Highly customizable: sandboxing, custom predicates ichiban/prolog vs otto vs go-lua prolog otto go-lua Language ISO Prolog ECMA Script Lua Paradigm Logic Object-oriented Object-oriented Go API database/sql-like original original Declarative Sandboxing Getting started Install latest version go get -u github.com/ichiban/prolog@latest Usage Instantiate an interpreter p := prolog.New(nil, nil) Or, if you want to expose standard input/output to your interpreter: p := prolog.New(os.Stdin, os.Stdout) Or, if you want a secure interpreter without any builtin predicates: // See examples/sandboxing/main.go for details. p := new(prolog.Interpreter) Load a Prolog program if err := p.Exec(` :- [abc]. % Load file 'abc' or 'abc.pl'. :- ['/path/to/abc']. % Load file '/path/to/abc' or '/path/to/abc.pl'. % You need to quote to contain / in the path. :- [library(dcg)]. % Load library 'library(dcg)'. % See examples/dcg/main.go for a complete example. human(socrates). % This is a fact. mortal(X) :- human(X). % This is a rule. `); err != nil { panic(err) } Run the Prolog program // Prolog program invocation takes a form of query. sols, err := p.Query(`mortal(Who).`) if err != nil { panic(err) } defer sols.Close() // Iterates over solutions. for sols.Next() { // Prepare a struct with fields which name corresponds with a variable in the query. var s struct { Who string } if err := sols.Scan(&s); err != nil { panic(err) } fmt.Printf("Who = %s\n", s.Who) // ==> Who = socrates } Built-in Predicates Category Indicator ISO? Description Implemented in Control true * Always succeeds. Prolog Constructs fail * Always fails. Prolog false Synonym for fail. Prolog call(Goal) * Calls Goal. Go ! * Cut. Prolog P, Q * Conjunction. Prolog Not only disjunction P; Q * but also If->Then; Prolog Else is supported. If->Then * If->Then. Prolog Calls Goal. If an catch(Goal, Catcher, exception is raised Recover) * and unifies with Go Catcher, calls Recover. throw(Exception) * Raises Exception. Go \+Goal * Succeeds if Goal Go fails. once(Goal) * Calls Goal at most Prolog once. Repeats until the repeat * proceeding code Go succeeds. Terminates the host halt(Status) * program with exit Go code Status. halt * Equivalent to halt Prolog (0). Unification Term1 = Term2 * Unifies Term1 with Go Term2. unify_with_occurs_check Unifies Term1 with (Term1, Term2) * Term2 if it doesn't Go create cyclic terms. Term1 \= Term2 * Not unifiable. Prolog Type var(Term) * Succeeds if Term is Go Testing a variable. atom(Term) * Succeeds if Term is Go an atom. integer(Term) * Succeeds if Term is Go an integer. float(Term) * Succeeds if Term is Go a float. Succeeds if Term is atomic(Term) * neither a variable Prolog nor compound. compound(Term) * Succeeds if Term is Go a compound. nonvar(Term) * Succeeds if Term is Prolog not a variable. Succeeds if either number(Term) * integer(Term) or Prolog float(Term). Term functor(Term, Name, Succeeds if Term has Processing Arity) * a name Name and Go arity Arity. Succeeds if the arg(Arg, Term, Value) * Arg-th argument of Go Term unifies with Value. Succeeds if List is Term =.. List * a list of the Go functor and arguments of Term. Creates a copy of In copy_term(In, Out) * and unifies it with Go Out. Compares Term and compare(Order, Term1, * Term2 and unifies Go Term2) Order with either <, =, or >. Either Term1 == Term1 @=< Term2 * Term2 or Term1 @< Prolog Term2. Equivalent to Term1 == Term2 * compare(=, Term1, Prolog Term2). Equivalent to \ Term1 \== Term2 * +compare(=, Term1, Prolog Term2). Equivalent to Term1 @< Term2 * compare(<, Term1, Prolog Term2). Equivalent to Term1 @> Term2 * compare(>, Term1, Prolog Term2). Either Term1 == Term1 @>= Term2 * Term2 or Term1 @> Prolog Term2. Evaluates Expression Arithmetic Number is Expression * and unifies the Go result with Number. Succeeds if both Exp1 =:= Exp2 * Exp1 and Exp2 Go evaluate to the same number. Succeeds unless both Exp1 =\= Exp2 * Exp1 and Exp2 Go evaluate to the same number. Succeeds if Exp1 evaluates to a Exp1 < Exp2 * number that is less Go than what Exp2 evaluates to. Exp1 =< Exp2 * Either Exp1 == Exp2 Go or Exp1 < Exp2. Succeeds if Exp1 evaluates to a Exp1 > Exp2 * number that is Go greater than what Exp2 evaluates to. Exp1 >= Exp2 * Either Exp1 == Exp2 Go or Exp1 > Exp2. Tells the interpreter that the Clause dynamic(Name/Arity) * predicate indicated Go by Name/Arity is dynamic. Tells the interpreter that the built_in(Name/Arity) predicate indicated Go by Name/Arity is built-in. Succeeds if Head and clause(Head, Body) * Body unify with a Go clause. Succeeds if the current_predicate(Name/ * predicate indicated Go Arity) by Name/Arity defined. asserta(Term) * Prepends Term to the Go clauses. assertz(Term) * Appends Term to the Go clauses. retract(Term) * Remove a clause that Go unifies with Term. Remove the predicate abolish(Name/Arity) * indicated by Name/ Go Arity. Lists all Template All findall(Template, Goal, * for each solution of Go Solutions List) Goal and unifies it with List. Creates a bag bagof(Template, Goal, (multiset) of Bag) * Template for each Go solution of Goal and unifies it with Bag. Creates a set of setof(Template, Goal, * Template for each Go Set) solution of Goal and unifies it with Set. Unifies Stream with Stream current_input(Stream) * the current input Go stream. Unifies Stream with current_output(Stream) * the current output Go stream. Sets the current set_input(Stream) * input stream to Go Stream. Sets the current set_output(Stream) * output stream to Go Stream. Creates a stream of open(File, Mode, * Mode by opening File Go Stream, Options) and unifies it with Stream. open(File, Mode, Equivalent to open Stream) * (File, Mode, Stream, Prolog []). Closes Stream. If close(Stream, Options) * [force(true)] is Go provided as Options, ignores errors. close(Stream) * Equivalent to close Prolog (Stream, []). stream_property(Stream, Unifies Property Property) * with a stream Go property of Stream. at_end_of_stream Succeeds if Stream (Stream) * is at the end of the Prolog stream. Equivalent to at_end_of_stream * current_input_stream Prolog (S), at_end_of_stream(S) set_stream_position * Sets the position of Go (Stream, Position) Stream to Position. Unifies Char with a Character I get_char(Stream, Char) * single-rune atom of Go /O the next rune from Stream. Equivalent to get_char(Char) * current_input(S), Prolog get_char(S, Char). Unifies Code with an get_code(Stream, Code) * integer of the next Prolog rune from Stream. Equivalent to get_code(Code) * current_input(S), Prolog get_code(S, Code). Similar to get_char peek_char(Stream, Char) * (Stream, Char) but Go doesn't consume the next rune. Equivalent to peek_char(Char) * current_input(S), Prolog peek_char(S, Char). Similar to get_code peek_code(Stream, Code) * (Stream, Code) but Prolog doens't consume the next rune. Equivalent to peek_code(Code) * current_input(S), Prolog peek_code(S, Code). put_char(Stream, Char) * Writes a single-rune Prolog atom Char to Stream. Equivalent to put_char(Char) * current_output(S), Prolog put_char(S, Char). Writes a rune put_code(Stream, Code) * represented by Go integer Code to Stream. Equivalent to put_code(Code) * current_output(S), Prolog put_code(S, Code). nl(Stream) * Writes a newline to Prolog Stream. Equivalent to nl * current_output(S), Prolog nl(S). Unifies Byte with Binary I/O get_byte(Stream, Byte) * the next byte from Go Stream. Equivalent to get_byte(Byte) * current_input(S), Prolog get_byte(S, Byte). Similar to get_byte peek_byte(Stream, Byte) * (Stream, Byte) but Go doesn't consume the next byte. Equivalent to peek_byte(Byte) * current_input(S), Prolog peek_byte(S, Byte). Writes a byte put_byte(Stream, Byte) * represented by an Go integer Byte to Stream. Equivalent to put_byte(Byte) * current_output(S), Prolog put_byte(S, Byte). read_term(Stream, Term, Reads a term from Term I/O Options) * Stream and unifies Go Term with it. Equivalent to read_term(Term, * current_input(S), Prolog Options) read_stream(S, Term, Options) Equivalent to read(Stream, Term) * read_term(Stream, Prolog Term, []). Equivalent to read(Term) * current_input(S), Prolog read(S, Term). write_term(Stream, * Write Term to Go Term, Options) Stream. Equivalent to write_term(Term, * current_output(S), Prolog Options) write_term(S, Term, Options). Equivalent to write(Stream, Term) * write_term(Stream, Prolog Term, []). Equivalent to write(Term) * current_output(S), Prolog write(S, Term). Equivalent to writeq(Stream, Term) * write_term(Stream, Prolog Term, [quoted(true), numbervars(true)]). Equivalent to writeq(Term) * current_output(S), Prolog writeq(S, Term). Equivalent to write_canonical(Stream, * write_term(Stream, Prolog Term) Term, [quoted(true), ignore_ops(true)]). Equivalent to write_canonical(Term) * current_output(S), Prolog write_canonical(S, Term). Declares Name is an operator of Operator op(Priority, Specifier, * Priority. Specifier Go Name) is one of fx, fy, xf, yf, xfx, xfy, or yfx. current_op(Priority, Unifies an operator Specifier, Name) * of Priority, Go Specifier, and Name. Char char_conversion(In, Declares a char Conversion Out) * conversion from In Go to Out. current_char_conversion Unifies a char (In, Out) * conversion from In Go to Out. Atom atom_length(Atom, Succeeds if the Processing Length) * length of Atom Go unifies with Length. atom_concat(Atom1, Succeeds if Atom3 is Atom2, Atom3) * a concatination of Go Atom1 and Atom2. Succeeds if SubAtom can be unified with a sub atom of Atom where Before is the sub_atom(Atom, Before, number of runes Length, After, SubAtom) * before SubAtom, Go Length is the length of SubAtom, and After is the number of runes after SubAtom. Succeeds if Atom atom_chars(Atom, Chars) * consists of Go single-rune atoms in the list Chars. Similar to atom_chars(Atom, atom_codes(Atom, Codes) * Chars) but integers Go represents runes of the atom. Succeeds if a single-rune atom char_code(Char, Code) * Atom and an integer Go Code represents the same rune. Succeeds if Number is a number which number_chars(Number, string Chars) * representation Go consists of single-rune atoms in a list Chars. Similar to number_codes(Number, * number_chars(Number, Go Codes) Chars) but a list of integers. Flag set_prolog_flag(Flag, * Sets a Prolog flag Go Value) Flag to Value. current_prolog_flag Succeeds if a Prolog (Flag, Value) * flag Flag is set to Go Value. Loads files or libraries. File can be an atom Program consult(File) describing a file Go path, library(Name) describing a library, or a list of them. Equivalent to .(File, Files) consult(.(File, Prolog Files)). List append(List1, List2, Succeeds if List3 is Processing List3) the concatination of Prolog List1 and List2. member(Elem, List) Succeeds if Elem is Prolog a member of List. Succeeds if Length length(List, Length) is the length of Prolog List. Succeeds if Elem is nth(N, List, Elem) the N-th element of Prolog List. Term Unifies Out with an Expansion expand_term(In, Out) expanded term for Go In. Succeeds if an Environment environ(Key, Value) environment Go Variable varialble Key has a value Value. License Distributed under the MIT license. See LICENSE for more information. Contributing See ARCHITECTURE.md for architecture details. 1. Fork it (https://github.com/ichiban/prolog/fork) 2. Create your feature branch (git checkout -b feature/fooBar) 3. Commit your changes (git commit -am 'Add some fooBar') 4. Push to the branch (git push origin feature/fooBar) 5. Create a new Pull Request About The only reasonable scripting engine for Go. Topics go golang interpreter prolog logic-programming Resources Readme License MIT License Stars 256 stars Watchers 7 watching Forks 10 forks Releases 13 v0.8.0 Latest Jan 1, 2022 + 12 releases Packages 0 No packages published Used by 2 * @ichiban @ichiban / proxima * @ichiban @ichiban / kagomelog Languages * Go 98.5% * Prolog 1.5% * (c) 2022 GitHub, Inc. * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.