In Prolog code, one may pass instructions to the compiler by using "headless" Horn clauses which have no head relation to the left of the left-pointing material implication ':-' (⇐). For example, to import Modules or declare Unit Test Code:
:- begin_tests(lists).
:- use_module(library(lists)).
test(reverse) :- reverse([a,b], [b,a]).
:- end_tests(lists).
Evidently the location inside the source file of the headless Horn clauses is important.
A Horn clause
HEAD :- BODY1, BODY2, .... , BODYN
is understood be be equivalent to the logical expression
body_1 ∧ body_2 ∧ .... ∧ body_n ⇒ head
or, as this is understood to be classical logic, using the equivalence rules of boolean algebra:
¬body_1 ∨ ¬body_2 ∨ .... ∨ ¬body_n ∨ head
In the case of headless clauses, we are thus asserting a negation:
:- begin_tests(lists).
in principle means that we assert that begin_tests(lists)
is not true.
(Indeed in Answer Set Programming, clauses of the above sort are used as "contradiction" to reject generated solution: :- move(D,P,T), blocked(D-1,P,T).
means "it is never true that move(D,P,T) ∧ blocked(D-1,P,T)", reject any potential solutions accordingly.)
I understand the pragmatic need for being able to specify code delimiters, source annotations, file meta information and other compiler instructions. But why does the instruction use :-
. Wouldn'it it have been cleaner to use some other symbol completely unrelated to the logical syntax, e.g. the #
traditionally used by C macros.
In SWI-Prolog, there is a clean alternative for this:
You can write:
?- Goal.
This syntax is completely analogous to queries, which, if you look closely, always are of the form ?- Goal
, even if you do not explicitly enter the ?-
.
Wouldn'it it have been cleaner to use some other symbol completely unrelated to the logical syntax, e.g. the # traditionally used by C macros.
As long as you are using Prolog's term syntax, the literal analogy to horn clauses cannot work since both a prefix operator and a postfix operator denote the very same term. A clause with an empty head is :- p.
and a clause with an empty body is p :- .
With appropriate operators both denote the term :-(p).
Since you can change operators dynamically, a term :-(p).
is thus highly ambiguous: it may denote a fact or a rule with an empty head.
In Prolog text, a read-term :-(Dir).
is called a directive. This is so since Edinburgh Prolog, that is since 1977. Originally (and still in many current implementations) the term Dir
was simply taken as a goal to be executed and a warning was produced in case of failure. For queries that show answers, the term ?-(Query).
was used which later became the prompt ?-
. That is, the top level loop prints ?-
for you.
In ISO Prolog, only a select number of directives is defined.
7.4.2 Directives 1 dynamic/1. 2 multifile/1. 3 discontiguous/1. 4 op/3. 5 char_conversion/2. 6 initialization/1. 7 include/1. 8 ensure_loaded/1. 9 set_prolog_flag/2.
General goals need to be wrapped with initialization/1
. They are executed after the entire Prolog text has been prepared for execution. Contrast this to directives which in many implementations are executed immediately with the current state of clauses read so far.
What has always escaped my comprehension is why systems perform singleton variable checks for directives and ?-
questions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With