I have most Compound Term, such as:
likes(a, b).
likes(c, b).
likes(a, d).
likes(b, c).
likes(c, a).
likes(a, f).
go(a, t).
go(t, d).
go(g, a).
go(f, g).
go(f, a).
I want to search Compound Tern, value of Atom is "a", value of the other Atom is any value.
The result of Prolog return:
likes(a, b).
likes(a, d).
likes(c, a).
likes(a, f).
go(a, t).
go(g, a).
go(f, a).
Please, help me
First you need to "reify" the predicate term. Your theory becomes:
do(likes, a, b).
do(likes, c, b).
do(likes, a, d).
do(likes, b, c).
do(likes, c, a).
do(likes, a, f).
do(go, a, t).
do(go, t, d).
do(go, g, a).
do(go, f, g).
do(go, f, a).
Add the following:
has_value(X) :- do(_, X, _)
has_value(X) :- do(_, _, X)
And you're done.
You could use meta-predicates like =.. to avoid changing your theory. Personally I think that's the wrong approach. Better to have the right formalisation of the problem from the start.
I've written here a generic helper. I thought that less builtins were needed...
search_facts_by_arg(Functor, Arg, C) :-
current_functor(Functor, Arity),
Arity >= 2, % because of 'value of the other Atom is any value.'
length(Args, Arity),
C =.. [Functor|Args],
clause(C, true),
once((arg(_, C, A), A == Arg)).
- current_functor(Functor, Arity)
- Arity >= 2
- length(Args, Arity)
- C =.. [Functor|Args]
- clause(C, true)
- once(Callable)
- arg(_, C, A)
- A == Arg
Phew...
test:
?- search_facts_by_arg(go, a, C).
C = go(a, t) ;
C = go(g, a) ;
C = go(f, a) ;
false.
edit: after @false' suggestion, the code could be simplified
search_facts_by_arg(Functor, Arg, C) :-
functor(C, Functor, 2),
clause(C, true),
once((arg(_, C, A), A == Arg)).
here is the functor/3 documentation. The essential builtin is clause/2, here another simplified way, using univ to build the 'template' head:
search_facts_by_arg(Functor, Arg, C) :-
C =.. [Functor,_,_],
clause(C, true),
once((arg(_, C, A), A == Arg)).