LANG=en
bash --version
prolog
¶# cd ~/publis/Tiny-Prolog-in-OCaml.git/
ls prolog/
cd prolog/
Let's build prolog
, it's really easy:
/usr/bin/make clean
/usr/bin/make
The binary prolog
that was just generated is an OCaml binary.
Ii is not native, but we don't care. If you want a native binary, just do this:
/usr/bin/make prolog.opt
cd ..
ls prolog/prolog prolog/prolog.opt
file prolog/prolog prolog/prolog.opt
There is half a dozen of examples:
ls -larth examples/*.pl
For instance, a tiny one is the following:
cd examples
cat odd.pl
even.pl
define the even integers.
The prolog
binary accepts a request as its last argument:
../prolog/prolog even.pl "even(o)." # an empty valuation: it's true!
../prolog/prolog even.pl "even(s(o))." # aucune théorie : c'est false !
../prolog/prolog even.pl "even(s(s(o)))." # une théorie vide : c'est true !
And prolog
can also find all the even integers! It will only display a few (15), but it could find them all.
../prolog/prolog even.pl "even(X)." # it will find 15 e
../prolog/prolog natural_integer_arithmetics.pl "lowerEq(s(s(o)), s(s(s(o))))." # 2 <= 3 ? yes
../prolog/prolog natural_integer_arithmetics.pl "lowerEq(s(s(s(s(o)))), s(s(s(o))))." # 4 <= 3 ? no
../prolog/prolog natural_integer_arithmetics.pl "sum(o,s(o),s(o))." # 0+1 = 1 ? yes
../prolog/prolog natural_integer_arithmetics.pl "sum(s(o),s(o),s(s(o)))." # 1+1 = 2 ? yes
../prolog/prolog natural_integer_arithmetics.pl "sum(s(o),o,s(s(o)))." # 1+1 = 1 ? no
odd
predicate¶cat even.pl
[ -f odd.pl ] && rm -vf odd.pl
echo "odd(s(o))." > odd.pl
echo "odd(s(s(X))) <-- odd(X)." >> odd.pl
../prolog/prolog odd.pl "odd(o)." # false
../prolog/prolog odd.pl "odd(s(o))." # true
../prolog/prolog odd.pl "odd(s(s(o)))." # false
Note: this example does NOT use anyone from my family. The names are purely imaginary.
The only thing we need to define at first is a predicate parent(X, Y)
that defines the fact that X is a father/mother/parent of Y. It is a direct down link in a family tree.
rm -vf aSmallFamily.pl
echo "parent(cyrill, renaud)." >> aSmallFamily.pl
echo "parent(cyrill, claire)." >> aSmallFamily.pl
echo "parent(renaud, clovis)." >> aSmallFamily.pl
echo "parent(valentin, olivier)." >> aSmallFamily.pl
echo "parent(claire, olivier)." >> aSmallFamily.pl
echo "parent(renaud, claudia)." >> aSmallFamily.pl
echo "parent(claire, gaelle)." >> aSmallFamily.pl
../prolog/prolog aSmallFamily.pl "parent(cyrill, renaud)." # true
../prolog/prolog aSmallFamily.pl "parent(claire, renaud)." # false
../prolog/prolog aSmallFamily.pl "parent(X, renaud)." # cyrill
../prolog/prolog aSmallFamily.pl "parent(X, gaelle)." # claire
../prolog/prolog aSmallFamily.pl "parent(X, olivier)." # claire, valentin
../prolog/prolog aSmallFamily.pl "parent(renaud, X)." # clovis, claudia
../prolog/prolog aSmallFamily.pl "parent(gaelle, X)." # {}
../prolog/prolog aSmallFamily.pl "parent(olivier, X)." # {}
Brother and sisters are defined by having a common parent, and cousins are defined by having a common grand-parent:
echo "brothersister(X,Y) <-- parent(Z,X), parent(Z,Y)." >> aSmallFamily.pl
echo "grandparent(X,Y) <-- parent(X,Z), parent(Z,Y)." >> aSmallFamily.pl
echo "cousin(X,Y) <-- grandparent(Z,X), grandparent(Z,Y)." >> aSmallFamily.pl
../prolog/prolog aSmallFamily.pl "brothersister(cyrill, claire)." # false
../prolog/prolog aSmallFamily.pl "brothersister(renaud, claire)." # true
../prolog/prolog aSmallFamily.pl "brothersister(claire, claire)." # true
../prolog/prolog aSmallFamily.pl "grandparent(X,olivier)." # cyrill
../prolog/prolog aSmallFamily.pl "grandparent(X,gaelle)." # cyrill
I will let you find a correct recursive definition of this predicate ancester
.
#echo "ancester(X,Y) <-- ancester(X,Z), grandparent(Z,Y)." >> aSmallFamily.pl
echo "ancester(X,Y) <-- parent(X,Y)." >> aSmallFamily.pl
echo "ancester(X,Y) <-- grandparent(X,Y)." >> aSmallFamily.pl
#echo "ancester(X,X)." >> aSmallFamily.pl
On peut vérifier tous les axiomes and règles qu'on a ajouté :
cat aSmallFamily.pl
Questions:
../prolog/prolog aSmallFamily.pl "parent(X,olivier)."
../prolog/prolog aSmallFamily.pl "grandparent(X,olivier)."
../prolog/prolog aSmallFamily.pl "ancester(X,olivier)."
../prolog/prolog aSmallFamily.pl "ancester(olivier,X),ancester(renaud,X)."
../prolog/prolog aSmallFamily.pl "ancester(X,olivier),ancester(X,renaud)."
../prolog/prolog aSmallFamily.pl "brothersister(gaelle,claudia)." # false
../prolog/prolog aSmallFamily.pl "cousin(gaelle,claudia)." # true
../prolog/prolog aSmallFamily.pl "brothersister(X,clovis)."
../prolog/prolog aSmallFamily.pl "cousin(X,clovis)."
That's it for today, folks!
Have a look to this other repository for more notebooks I wrote.