Search code examples
prologiso-prolog

Why must facts be grouped together in Prolog?


Say I am listing facts:

letter(a).
letter(b).
letter(c).
...
letter(z).
vowel(a).
consonant(b).
consonant(c).
consonant(d).
vowel(e).
consonant(f).
...
consonant(z).

If I declare the rules in 'alphabetical' order, I get the following warnings in the console:

Warning: /Users/…/prolog-example.pl:31:
  Clauses of vowel/1 are not together in the source-file
Warning: /Users/…/prolog-example.pl:32:
  Clauses of consonant/1 are not together in the source-file
Warning: /Users/…/prolog-example.pl:35:
  Clauses of vowel/1 are not together in the source-file
Warning: /Users/…/prolog-example.pl:36:
  Clauses of consonant/1 are not together in the source-file
Warning: /Users/…/prolog-example.pl:51:
  Clauses of vowel/1 are not together in the source-file

But if I do the following:

letter(a).
letter(b).
letter(c).
...
letter(z).
consonant(b).
consonant(c).
consonant(d).
...
consonant(z).
vowel(a).
vowel(e).
vowel(i).
vowel(o).
vowel(u).
vowel(y).

I dont get the warnings. Are the warnings just warnings or are they actual errors?


Solution

  • When a predicate definition is discontiguous, the predicate should be declared as such using the standard discontiguous/1 directive before its clauses. In your case:

    :- discontiguous([
        letter/1,
        vowel/,
        consonant/1
    ]).
    

    If you have discontiguous predicates without corresponding discontiguous/1 directives, the consequences depend on the used Prolog system. For example, SWI-Prolog and YAP will print warnings but accept all clauses. GNU Prolog will ignore clauses. ECLiPSe will report a compilation error. In the case the Prolog system doesn't throw an error, a warning is usually still printed as a predicate may be detected as discontiguous due to e.g. a simple typo in a clause head.