Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
tutorials:beginner:cram_prolog [2015/05/29 19:19] – gkazhoya | tutorials:beginner:cram_prolog [2022/05/26 12:32] (current) – [Using built-in predicates] schimpf | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Using Prolog for reasoning ====== | ====== Using Prolog for reasoning ====== | ||
+ | **Description: | ||
+ | |||
+ | **Previous Tutorial:** [[tutorials: | ||
+ | **Next Tutorial:** [[tutorials: | ||
==== Using built-in predicates ==== | ==== Using built-in predicates ==== | ||
Line 6: | Line 10: | ||
CRAM has its own primitive Prolog interpreter written in Common Lisp which can work natively with the Lisp data structures (as opposed to, e.g., SWI Prolog, which would need a complex mechanism for passing around Lisp data structures and converting Prolog results back into Lisp). | CRAM has its own primitive Prolog interpreter written in Common Lisp which can work natively with the Lisp data structures (as opposed to, e.g., SWI Prolog, which would need a complex mechanism for passing around Lisp data structures and converting Prolog results back into Lisp). | ||
- | It is implemented in the " | + | It is implemented in the '' |
<code lisp> | <code lisp> | ||
- | CL-USER> (asdf: | + | CL-USER> (asdf: |
- | CL-USER> (in-package :cram-reasoning) | + | CL-USER> (in-package :cram-prolog) |
</ | </ | ||
Executing Prolog queries is done by calling the '' | Executing Prolog queries is done by calling the '' | ||
<code lisp> | <code lisp> | ||
- | CRS> (prolog ' | + | PROLOG> (prolog ' |
(((?X . 1)) | (((?X . 1)) | ||
. # | . # | ||
Line 24: | Line 28: | ||
<code lisp> | <code lisp> | ||
- | CRS> (force-ll (prolog ' | + | PROLOG> (force-ll (prolog ' |
(((?X . 1)) ((?X . 2)) ((?X . 3))) | (((?X . 1)) ((?X . 2)) ((?X . 3))) | ||
</ | </ | ||
+ | |||
+ | === Using unbound variables === | ||
Variables in CRAM Prolog are represented by any symbol that starts with ''?'' | Variables in CRAM Prolog are represented by any symbol that starts with ''?'' | ||
Line 32: | Line 38: | ||
We can also have queries with multiple unbound variables, e.g.: | We can also have queries with multiple unbound variables, e.g.: | ||
<code lisp> | <code lisp> | ||
- | CRS> (defparameter *some-list* '((1) (2 3) (4 5 6))) | + | PROLOG> (defparameter *some-list* '((1) (2 3) (4 5 6))) |
*SOME-LIST* | *SOME-LIST* | ||
- | CRS> (force-ll (prolog `(and (member ?x , | + | PROLOG> (force-ll (prolog `(and (member ?x , |
- | | + | (length ?x ?x-len)))) |
(((?X 1) (?X-LEN . 1)) ((?X 2 3) (?X-LEN . 2)) ((?X 4 5 6) (?X-LEN . 3))) | (((?X 1) (?X-LEN . 1)) ((?X 2 3) (?X-LEN . 2)) ((?X 4 5 6) (?X-LEN . 3))) | ||
</ | </ | ||
Then we get one correct possible assignment for all the variables as one entry of the lazy list. | Then we get one correct possible assignment for all the variables as one entry of the lazy list. | ||
+ | It is important to remember that the ` is needed for unbound variables, not the ' or you will get an error. | ||
+ | |||
+ | === No solution === | ||
If there are no solutions for the query Prolog returns NIL: | If there are no solutions for the query Prolog returns NIL: | ||
<code lisp> | <code lisp> | ||
- | CRS> (prolog '(and (member ?x (1 2 3)) | + | PROLOG> (prolog '(and (member ?x (1 2 3)) |
- | | + | (< ?x 0))) |
NIL | NIL | ||
</ | </ | ||
Line 49: | Line 58: | ||
If there are no unbound variables in the query but the query itself is true, Prolog returns a list where bindings are NIL: | If there are no unbound variables in the query but the query itself is true, Prolog returns a list where bindings are NIL: | ||
<code lisp> | <code lisp> | ||
- | CRS> (force-ll (prolog '(> 4 0))) | + | PROLOG> (force-ll (prolog '(> 4 0))) |
(NIL) | (NIL) | ||
</ | </ | ||
- | + | === Using lisp with prolog code === | |
- | The CRAM Prolog interpreter finds solutions by performing a depth first search over the predicate tree, that it, it first searches for possible bindings for the first predicate, then branches into multiple search paths, one per each assignment and continues with the second predicate, and so on. The mechanism is the same as in any other Prolog implementation. | + | The CRAM Prolog interpreter finds solutions by performing a depth first search over the predicate tree, that it, it first searches for possible bindings for the first predicate, then branches into multiple search paths, one per each assignment, and continues with the second predicate, and so on. The mechanism is the same as in any other Prolog implementation. |
One difference between CRAM Prolog and conventional implementations is that some predicates can be proven by using a Lisp function and not through depth-first search over possible solutions. For that predicates '' | One difference between CRAM Prolog and conventional implementations is that some predicates can be proven by using a Lisp function and not through depth-first search over possible solutions. For that predicates '' | ||
<code lisp> | <code lisp> | ||
- | CRS> (force-ll (prolog ' | + | PROLOG> (force-ll (prolog ' |
(NIL) | (NIL) | ||
</ | </ | ||
Line 67: | Line 76: | ||
Please note that in Prolog there can (and usually are) multiple ways of proving the same predicate (multiple implementations), | Please note that in Prolog there can (and usually are) multiple ways of proving the same predicate (multiple implementations), | ||
- | We call predicate definitions //rules// or //facts//. For defining custom Prolog predicates CRAM Prolog uses the macro '' | + | We call predicate definitions //rules// or //facts//. For defining custom Prolog predicates CRAM Prolog uses the macro '' |
<code lisp> | <code lisp> | ||
- | CRS> (def-fact-group family-predicates () | + | PROLOG> (def-fact-group family-predicates () |
- | | + | (<- (grandparent ? |
- | | + | (parent ? |
- | | + | (parent ?x ? |
</ | </ | ||
Line 79: | Line 88: | ||
<code lisp> | <code lisp> | ||
- | CRS> (def-fact-group family-predicates () | + | PROLOG> (def-fact-group family-predicates () |
- | (<- (grandparent ? | + | |
- | | + | (parent ? |
- | | + | (parent ?x ?grandkid)) |
- | (<- (parent my-dad me)) | + | |
- | | + | (<- (parent me my-kid))) |
</ | </ | ||
Line 94: | Line 103: | ||
<code lisp> | <code lisp> | ||
- | CRS> (force-ll (prolog ' | + | PROLOG> (force-ll (prolog ' |
(NIL) | (NIL) | ||
- | CRS> (force-ll (prolog '(and (parent ? | + | PROLOG> (force-ll (prolog '(and (parent ? |
- | | + | (grandparent ? |
(((? | (((? | ||
</ | </ | ||
+ | |||
+ | |||
+ | Now that we are familiar with the CRAM Prolog syntax, let's dive right into resolving CRAM abstract entity descriptions, | ||
+ | |||
+ | **Next Tutorial:** [[tutorials: |