How to return the list to Prolog?

Let's say I have the following facts:

parent(bob, sam). %bob is sam parent parent(sara, sam). %sara is sam parent 

I wanted to know who were the parents-sam, and return them to the list and as such is used:

 list_parents(P, L) :- findall(Parent, parent(Parent, P), L). 

Now I want to ask the same question, but with only one argument:

 findParents(sam). 

I tried:

 findParents(Name) :- list_parents(Name, L). 

but so Prolog simply answers "True" .

+4
source share
3 answers

The thing with the prologue is that it's a bit different from most languages ​​(an understatement if each of them had one):

  • All variables are locally bounded.

  • Variable values ​​are invariant when they are tied (unified), unless otherwise off not untie it.

  • Predicates do not return a value in the usual sense. They either succeed or fail.

  • To get the value from testing a predicate, you evaluate the predicate by passing it something from your predicate. It does not matter whether you pass it a variable or associated value: predicate, the predicate will be successful, or will make a difference, if what the caller is combined with the fact that you gave him. If you pass a variable and calls the predicate combines it with non-variable value, your variable tied to this value. Think about it (a few), as if you had a procedural language, each function to return a bool and all parameters passed by reference.

What have you tried:

 findParents(Name) :- list_parents(Name, L). 

The variable L was combined with (been tied) to the list returned by findall/3 . And then he went out of scope.

If you want to actually do something with it returned (tied) value, you have to deal with him where he is in scope, or unify this value with that to which the predicate was called, and thus , pass it on the call stack. Or you can establish it in a database of facts and save it for later.

How the prolog works, the root predicate used to run your β€œprogram” defines the search tree in terms of the predicates in your database. Prologue "engine" and then searches the depths, from left to right in this tree. The predicate succeeds when the engine hits the leaf node of the search tree found you. Rollback in your predicate causes the engine to search for the next solution in the search tree.

As a result, everything you want to do persistently must happen as a side effect of the engine run evaluating the predicate. For example, print() is always carried out only once (when you enter the field) ... and as a side effect print everything that you asked to print. Rolling back print does not cancel printing, but print() will fail again.

+5
source

you can print the list, if you want the user to be able to see it something like:

 findParents(Name):- list_parents(Name,L), print(L). 

but it's definitely not coming back. remember that in the prologue there are no functions and, therefore, no "return value". you can simulate the function of writing foo (Args, Return), but you can always refer to it as the foo (X, sam) - sometimes it will give what you want, sometimes it will not, sometimes it will be broken.

+2
source

Library func provides syntax functions return values in SWI-Prolog. In this example, you can print all parents sam , writing writeln(list_parents $ sam) :

 :- initialization(main). :- use_module(library(func)). main :- writeln(list_parents $ sam). list_parents(P, L) :- findall(Parent, parent(Parent, P), L). parent(bob, sam). %bob is sam parent parent(sara, sam). %sara is sam parent findall (Parent, parent (Parent, P), L). :- initialization(main). :- use_module(library(func)). main :- writeln(list_parents $ sam). list_parents(P, L) :- findall(Parent, parent(Parent, P), L). parent(bob, sam). %bob is sam parent parent(sara, sam). %sara is sam parent 

Similarly, you can define a function with several parameters such as:

 % return a item at an index in a list. nth0((Index,List),ToReturn) :- nth0(Index,List,ToReturn). a list. % return a item at an index in a list. nth0((Index,List),ToReturn) :- nth0(Index,List,ToReturn). ToReturn): - % return a item at an index in a list. nth0((Index,List),ToReturn) :- nth0(Index,List,ToReturn). 

... and then use it as follows:

 example :- ListIndex = (nth0 $(0,[1,2,3,4])), %returns 1, which is the first item in this list writeln(ListIndex). returns example :- ListIndex = (nth0 $(0,[1,2,3,4])), %returns 1, which is the first item in this list writeln(ListIndex). list example :- ListIndex = (nth0 $(0,[1,2,3,4])), %returns 1, which is the first item in this list writeln(ListIndex). 
+2
source

All Articles