酷兔英语

章节正文

setof

The built-in Prolog predicate setof(+Template, +Goal, -Set) binds Set to the list of all instances of Template satisfying the goal Goal.

 

For example, given the facts and rule:

happy(fido).
happy(harry).
happy(X) :- rich(X).
rich(harry).

it follows that

?- setof(Y, happy(Y), Set).
Y = _G180
Set = [fido, harry] ;
false.

Notice that:

  • there are two ways to prove that harry is happy
    • from the fact happy(harry).
    • from the rule and the fact rich(harry).
    However, harry only appears once in the binding for Set;
  • the binding for Set is in sorted order.

Compare:

?- bagof(Y, happy(Y), Bag).
Y = _G180
Bag = [fido, harry, harry] ;
false.

and

?- findall(Y, happy(Y), Bag).
Y = _G180
Bag = [fido, harry, harry] ;
false.

The differences between bagof and findall on the one hand, and setof on the other hand, include the fact that with setof, you get sorted order and no repetitions. (For differences between bagof and findall, see findall.)

setof will fail (and so not bind Set) if the there are no instances of Template for which Goal succeeds - i.e. effectively it fails if Set would be empty. bagof also fails in these circumstances, while findall does not (it binds the variable that is its third argument to the empty list, or, if the third argument is instantiated, it succeeds if the third argument is the empty list).

 

side-effects

Prolog is supposedly a declarative language - that is, one which specifies relationships between concepts using facts and rules and then uses a logic engine to answer queries that relate to those facts and rules, typically by finding bindings for variables that allow queries to succeed.

 

However, in "real" Prolog, there are built-in predicates that do no comform to this pattern. These include input-output "predicates" like see, seeing, seen, tell, telling, told, write, nl, prin, print, put, and read, get, get_byte, flush_output. All of these predicates succeed or fail independent of any logicalaspect of the problem being solved - normally, in fact, they will succeed unless there is an error relating to the external input/output system - e.g. it may not be possible to read from a file because the user does not have permission to access the file, or because the file does not exist.

Even more extra-logical are assert, asserta, assertz and retract, retractall, which even change the program that is running.

Side-effects take Prolog programs out of the world of strict logic (as does the cut, which changes the way the inference engine operates in solving a query). Programs with side-effects are harder to analyse that programs without side-effects. The practical impact of side-effects on the understandabilty of Prolog programs depends on how they are used. For example, using memoisation to record facts inferred in order to save re-calculation is probably harmless, but using assert to create new rules might in some cases make debugging a program next to impossible. Use side-effects with care.

 

singleton variables

SWI Prolog sometimes produces an warning message like this:

% cat example.pl
happy(Pet) :-
   dog(Pet),
   walkies(Oet).
% prolog -s example.pl
Warning: example.pl:1:
        Singleton variables: [Oet]
...

This is alerting you to the fact that the variableOet has only been used once in the rule it appears in. Such variables are often (but not always) spelling mistakes. In this case, Oet should have been Pet.

 

Sometimes singleton variable reports are caused by the programmer trying to write helpful, readable code, like this version of member:

member(Item, [Item | Rest]).
member(Item, [NotItem | Rest]) :-
    + Item = NotItem,
    member(Item, Rest).

Prolog would report

      Singleton variables: [Rest]

for such code, because the helpfully-named variable Rest is only used once in member(Item, [Item | Rest]). The solution is to put an underscore ( _ ) at the start of this instance of Rest, thus replacing member(Item, [Item | Rest]). with member(Item, [Item | _Rest]). SWI Prolog will treat _Rest as a don't-care variable and not report it.

 

 

spy

The built-in pseudo-predicate spy allows one to trace the execution of a query in a selective manner. If you want to find out about each time that a particular predicate is called, you spy that predicate: see example below.

 

?- listing(happy).
happy(A) :-
        rich(A).
true.
?- listing(rich).
rich(fred).
true.
?- spy(rich).
% Spy point on rich/1
true.
[debug]  ?- happy(fred).
   Call: (8) rich(fred) ? creep
   Exit: (8) rich(fred) ? creep
   Exit: (7) happy(fred) ? creep
true.

As you can see, the call to rich is traced, but not much else. See also trace, which traces the execution of everything.

Turn spying off with nospy:

[debug]  ?- nospy(rich).
% Spy point removed from rich/1
true.

 

 

static

A Prolog procedure is static if its facts/rules do not change during the execution of the program of which they are part. This is the default: most Prolog procedures are static. The opposite of static is dynamic.

 

 

structures

Structures in Prolog are simply objects that have several components, but are treated as a single object. Suppose that we wish to represent a date in Prolog - dates are usually expressed using a day, a month, and a year, but viewed as a single object. To combine the components into a single structure, we choose a functor, say date, and use it to group the components together - for the date usually expressed as 21 March 2004, we would probably write

 

date(21, mar, 2004)

Note that the order of the components is our choice - we might have instead written date(2004, mar, 21) The choice of functor is arbitrary, too.

 

 

The components between the parentheses are referred to as arguments. Thus in the date example, the arguments are 21, mar, and 2004.

Structures may be nested, too - the following example groups a name and a date, perhaps the person's date of birth:

persondata(name(smith, john), date(28, feb, 1963))

This term has two arguments, the first being name(smith, john) and the second being date(28, feb, 1963)

 

See also Bratko, section 2.1.3. 



文章标签:词典  

章节正文