In a simple batch file - wizardofosmium/porolog GitHub Wiki
Using Porolog In a simple batch file
Accessing the Gem
As usual, you need to require the gem
require 'porolog'
Since this is a simple batch file, there is no harm in including Porolog
include Porolog
Now you can use and define Porolog methods globally.
Declaring Predicates
All the builtin predicates are available and can be declared using builtin
to create a global method to access the builtin predicate. See available builtin predicates in v1.0.0.
builtin :member
Your predicates need to be defined in a similar manner.
predicate :my_rule
Defining Facts
Now, define a fact.
my_rule(0, 0, 0).fact!
Porolog provides four fact methods:
fact!
cut_fact!
fallacy!
cut_fallacy!
These provide shorthand definitions for the corresponding Prolog:
info(1).
info(2) :- !.
info(3) :- fail.
info(4) :- !,fail.
So, using Porolog these would be:
predicate :info
info(1).fact!
info(2).cut_fact!
info(3).fallacy!
info(4).cut_fallacy!
Defining Rules
Rules are defined by using the <<
operator and an Array of predicate calls. For example:
my_rule(:X, :Y, :Z) << [
member(:X, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
member(:Y, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
noteq(:X, :Y),
is(:Z, :X, :Y) {|x, y| x + y }
]
Pruning
Cuts are specified by using :CUT
. So, for example, to iterate only through the Ys
my_rule(:X, :Y, :Z) << [
member(:X, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
:CUT,
member(:Y, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
noteq(:X, :Y),
is(:Z, :X, :Y) {|x, y| x + y }
]
Failing
A fail is represented by false
.
my_rule(:X, :Y, :Z) << [
member(:X, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
member(:Y, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
write(:X, :Y),
false
]
The Complete Example
require 'porolog'
include Porolog
builtin :member
predicate :my_rule
my_rule(0, 0, 0).fact!
my_rule(:X, :Y, :Z) << [
member(:X, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
member(:Y, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
noteq(:X, :Y),
is(:Z, :X, :Y) {|x, y| x + y }
]
puts my_rule(:X, :Y, :Z).solve.map(&:inspect)
puts my_rule(:X, :Y, :Z).solve_for(:Z).inspect