开发者

Prolog lists and parameters and return values

I'm new to prolog and I just can't figure this out.

I'm trying to build a simple program that receives a list of predicates, searches for a specific predicate in the list, and applies a function to that predicate's parameters.

Something along these lines:

?- program([pred1(a,b,p), pred2(d,b,p), pred2 (a,c,p)]). 

program (list1) :- 
search(pred2(X,Y,p),list1).
doSomething (X,Y) % with the X and Y returned from search function, both of them.

Basically, I want to use all values that would return from an objective search(pred2(X,Y,p),list1) and use them on another function.


Okay, I tried some stuff in prolog and came to this:

member(X, [X | _]).

member(X, [_ | R]) :- member(X, R).

prog(L1,Out) :- member(pred2(X,Y), L1).

?- prog ([(pred1(a,b),pred2(c,b),pred2(d,a)],Out).

It gives true 2 times as it is supposed to, but I wanted to get Out = [c,b] and Out = [d,a]. How I can achieve this?

Regarding Oak's answer: I get that it isn't a procedural language but I can't figure out how to access values and use them in prolog. Your example wasn't th开发者_如何转开发at helpful.


For starters, I would avoiding calling these things "functions". Prolog is not a procedural language, and rules / predicates are not functions.

Basically, when you use a rule you're really asking Prolog, "give me all the values which will satisfy this rule". The rule, by itself, does not return anything.

So say you had the following in a procedural language:

f(g(3))

How would you do it in Prolog? You would need to write some predicate f(X,Y) and some predicate g(X,Y), and then you would need to use the query f(3,Y), g(Y,Z) - which means to ask Prolog to find you values for Y and Z which will satisfy this. Z is what you're interested in.


the best way to approach these filter & project requirements in prolog in my opinion is to write your filter expression such that it takes one argument and succeeds if the input argument passes the filter -

iseven(Num) :- 0 is Num % 2 .

Then write the the projection code as taking one argument that is the input, and one that is the output -

triple(NumIn, NumOut) :- NumOut is NumIn * 3 .

Then tie them together -

triple_evens(NumIn, NumOut) :- iseven(NumIn), triple(NumIn, NumOut).

Then to run this on every member of a list, we should use findall -

triple_evens_in_list(Lin, Lout) :-
    findall(Num, ( member(NumL, Lin),
                   triple_evens(NumL, Num)
                 ), LOut).

This could be generalized to take as arguments the name of the filter & map predicates of course. And it could be compressed down to one stmt too in the form -

findall(Num, ( member(M, List), 0 is M % 2, Num is M * 3 ), ListOut).
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜