What is the difference between head and predication

The ISO Prolog standard notes

head (of a rule): A predication, distinguished by its context.

predication: A predicate with arity N and a sequence of N arguments.

predicate: An identifier together with an arity.

clause: A fact or a rule. It has two parts: a head, and a body.

clause noted because a clause is not just a head and this relates to just the head of a clause.


So my take is that there can be many heads for one predication, e.g.

predication

append(_,_,_)

head

append([], A, A)
append([A|B], C, [A|D])

Is this correct?


The distinction is usually just ignored but for my problem the distinction is needed, so it needs to be correct.


Demonstration with code

?- use_module(library(lists)).
true.

?- compound_name_arity(Predication,append,3),nth_clause(lists:Predication,Index,Ref),clause(Module:Head,_,Ref),numbervars(Predication,0,_,[singletons(true)]),numbervars(Head).
Predication = append(_, _, _),
Index = 1,
Ref = <clause>(0000000006240B20),
Module = lists,
Head = append([], A, A) ;
Predication = append(_, _, _),
Index = 2,
Ref = <clause>(00000000067ACAA0),
Module = lists,
Head = append([A|B], C, [A|D]).

Personal notes

SWI-Prolog has a few predicates for looking at properties of internal structures, in particular
clause_property/2 - clause_property(+ClauseRef, -Property)
predicate_property/2 - predicate_property(:Head, ?Property)

clause/3 clause(:Head, ?Body, ?Reference) can convert a head to a clause reference or a clause reference to a head, thus it would seem there is a one to one correspondence between clause reference and head. If so then why two different property predicates?

If one looks at the properties returned by predicate_property/2 for predicates with many different clauses, facts with many clauses are a good example, then it becomes apparent that properties are not unique per head but unique per predication, thus head makes more sense as predication and the predicate name makes more sense as predication_property.

So think of predicate_property(:Head, ?Property) as predication_property(:Predication, ?Property)


Likewise

predicate_name/2 - predicate_name(:Head, -PredName:string) as
predicatation_name(:Predication, -Predicate_name) where Predicate_name is a string.

current_predicate/2 - current_predicate(?Name, :Head) as
current_predicate(?Name, :Predication)

rule/2 - rule(:Head, -Rule) as
rule(:Predication, -Rule)

rule/3 - rule(:Head, -Rule, -Ref) as
rule(:Predication, -Rule, - Ref)

current_arithmetic_function/1 - current_arithmetic_function(?Head) as
current_arithmetic_function(?Predication)

current_format_predicate/2 - Need to understand this one first.

retractall/1 - retractal(+Head) as
retractall(+Predication)

pi_head/2 - pi_head(?PredicateIndicator, ?Goal) as
pi_head(?PredicateIndicator, ?Predication)

head_name_arity/3 - head_name_arity(?Goal, ?Name, ?Arity) as
head_name_arity(?Predication, ?Name, ?Arity)

current_predicate_wrapper/4 - Need to understand this one first.
wrap_predicate/4 - Need to understand this one first.

inferred_meta_predicate/2 - Need to understand this one first.
infer_meta_predicate/2 - Need to understand this one first.

iso_builtin_predicate/1 - iso_builtin_predicate(?Head:callable) as
iso_builtin_predicate(?Predication) where Predication is a callable term.


Predicates that use head

clause/2 - clause(:Head, ?Body)


When converting compiled code back into human readable code it is nice to have variable names like A,B,C. It is also nice to have the variable names correlate between the head and the body, the following code sample does this.

?- use_module(library(lists)).
true.

?- ?- current_predicate(append,Predication),rule(Predication,Rule),numbervars(Rule),numbervars(Predication,0,_,[singletons(true)]).
Predication = append(_, _, _),
Rule = append([], A, A) ;
Predication = append(_, _, _),
Rule =  (append([A|B], C, [A|D]):-append(B, C, D)) ;
Predication = append(_, _),
Rule =  (append(A, B):-must_be(list, A), append_(A, B)) ;
false.

How to check if a predicate uses a predication or head? Use the append predicates to check the results.

clause/2 uses a head and so returns multiple answers while predicate_name/2 uses a predication and returns a single answer.

?- clause(append(_,_,_),Body).
Body = true ;
Body = append(_28534, _27022, _28540).

?- predicate_name(append(_,_,_),Name).
Name = "append/3".

In trying to understand what frame is with regards to Environment Stack bumped into
Frame (artificial intelligence) which notes

Each piece of information about a particular frame is held in a slot. The information can contain:

  • Facts or Data
    • Values (called facets)
  • Procedures (also called procedural attachments)
    • IF-NEEDED : deferred evaluation
    • IF-ADDED : updates linked information
  • Default Values
    • For Data
    • For Procedures
  • Other Frames or Subframes

At present don’t know if all of this is related to Prolog but it is the first time I have seen all of the terminology used in one place based on a historical perspective.

Ref: “A Framework for Representing Knowledge” by Marvin Minsky (PDF)

2 Likes

I also find this confusing. Reminds me of this discussion.

1 Like