Rules about rules (and sorts)?

I have a few questions regarding rules, terms, and sorts (datatypes):

(1) I occasionally see the error “predicate not defined”. This happens with rules like scared(P) :- no_escape(P), faces_conflict(P), is_weaker(P) when I’ve previously written is_weaker(john), faces_conflict(john) but not written anything about no_escape.

  • (1A) Does SWI-Prolog (or all Prologs?) require seeing a term on its own before it is used in a rule? There is no default to false or undetermined?

  • (1B) If I must provide a term on its own before using it in a rule, does it need to be grounded? Is there a way to provide something like a function signature in imperative programming where I define the arity, datatypes, and return type – without grounding.

(2) What is the correct way to accomplish disjunction/or in the body of a rule? Do I just write multiple versions of the same rule and pattern matching selects the ones that fire:

fire :- enemy_in_range.
fire :- bored.

(3) I’ve read that programs with datatypes in Prolog are called “sorted” or “many-sorted”. I don’t mean datatypes for exchanging data.

  • (3A) How is this accomplished in SWI-Prolog? For example, if I want to specify can_run(P) but only if person(P). I can do this in a rule using an “and”(,) but am looking for something like can_run(P::person).
  • (3B) Does using sorts improve performance by filtering down the search space?

This only answers select parts of your many questions, as to give you something back faster than more in depth.


I know you are asking questions about other logics based on Prolog but for just Prolog, for a simple query where no dynamic/1 directive has been used for the predicate, the predicate is not defined and not in any module then

?- no_escape(P).
ERROR: Unknown procedure: no_escape/1 (DWIM could not correct goal)

where there is currently no defined predicate, E.g.

?- listing(M:no_escape(_)).
ERROR: procedure `_7900:no_escape(_7906)' does not exist (DWIM could not correct goal)
^  Exception: (13) setup_call_catcher_cleanup(system:true, prolog_listing:listing_(_20:no_escape(_18), []), _8912, prolog_listing:close_sources) ? abort
% Execution Aborted

there is no default to false or undetermined.


However if dynamic/1 is used then

?- dynamic no_escape/1.
true.

?- no_escape(P).
false.

?- listing(M:no_escape(_)).
:- dynamic no_escape/1.

Use ;. Note in the following the ; is placed on a separate line for the purpose of making it apparent that ; is used instead of , which can be easily missed when placed at the end of the line.

?- [user].
|: disjuction_in_clause(V) :-
|: V = a
|: ;
|: V = b
|: ;
|: V = c.
|:   % Enter Ctrl-D
% user://1 compiled 0.00 sec, 1 clauses
true.

?- disjuction_in_clause(V).
V = a ;
V = b ;
V = c.

If you don’t want choice points left, add the appropriate cuts (!).

The other was as you note is to do disjunction with multiple clauses for a rule.

I can’t give hard and fast rules about when to use multiple clauses or a single clause but after writing several hundred different ones it does get easier to pick.

1 Like

@EricGT . Thank you. Getting started with Prolog has many little pain points and these are some of them.

@jan , can you give any advice regarding question #3 on “sorts” in Prolog?

Note that Prolog is not s(CASP). The SWI-Prolog s(CASP) implementation allows writing the s(CASP) program in Prolog, uses clause/2 to collect the program and compile it to a representation suitable for the s(CASP) solver. Prolog itself has several ways to deal with undefined predicates, some already mentioned by @EricGT. Handling undefined as false is more common in s(CASP) and the only way the original operates. For SWI-Prolog you can set

 :- set_prolog_flag(scasp_unknown, fail).

As you do, write separate clauses. Maybe we’ll support inline disjunction at some point (compiling it to an anonymous predicate). I’m not sure it will be an improvement though. For example, think about the explanation.

Would only be syntactic sugar, no? Note that there is a hook called scasp_expand_program/4 that may be defined in the module implementing the s(CASP) program that can be used to transform the program.

I see no reasons for this to be any different wrt optimization. s(CASP) performance is quite hard to predict. It may be wise to study some of the papers and presentations on Gopal Gupta’s home page.

1 Like