title: How can I use a functor name like a variable in Prolog?
body: <p>We have this assignment for our Prolog course. After two months of one hour per week of Prolog, it is still an enigma to me, my thinking seems unable to adapt from procedural languages - yet.</p>
  
  <p>There is a knowledge base containing predicates/functors with the same name and arities 1, 2 and 3.
  The call form should be </p>
  
  <blockquote>
    <p>search(functor_name, argument, S).</p>
  </blockquote>
  
  <p>The answers should find all occurrences with this functor name and argument, regardless of arity.
  The answers should be of the form:</p>
  
  <pre><code>S = functor_name(argument);
  S = functor_name(argument,_);
  S = functor_name(_,argument);
  S = functor_name(argument,_,_);
  S = functor_name(_,argument,_);
  S = functor_name(_,_,argument);
  false.
  </code></pre>
  
  <p>I have found out that I could use call to test if the entry in the knowledge base exists.</p>
  
  <p>But call does not seem to work with a variable for the functor name. I am totally baffled, no idea how to use a variable for a functor name.</p>
  
  <p>UPDATE:</p>
  
  <p>My question has been partly answered.
  My new code gives me true and false for arities 1, 2 and 3 (see below).</p>
  
  <pre><code>search(Person,Predicate) :-
     ID = Person, Key = Predicate, current_functor(Key,1),
     call(Key,ID)
   ; ID = Person, Key = Predicate, current_functor(Key,2),
     (call(Key,ID,_);call(Key,_,ID))
   ; ID = Person, Key = Predicate, current_functor(Key,3),
     (call(Key,ID,_,_);call(Key,_,ID,_);call(Key,_,_,ID)).
  </code></pre>
  
  <p>UPDATE2:</p>
  
  <p>Another partial answer has come in. That one gives me S as a list of terms, but the "other" arguments are placeholders:</p>
  
  <pre><code>search2(Predicate, Arg, S) :-
     ( Arity = 2 ; Arity = 3 ; Arity = 4 ),
     functor(S, Predicate, Arity),
     S =.. [_,Predicate|Args],
     member(Arg, Args).
  </code></pre>
  
  <p>The result is quite nice. Still missing: the Predicate should not be inside the brackets and the other arguments should be taken literally from the knowledge base, not written as placeholders. The current result looks like this:</p>
  
  <pre><code> ?- search2(parent,lars,S).
  S = parent(parent, lars) ;
  S = parent(parent, lars, _G1575) ;
  S = parent(parent, _G1574, lars) ;
  S = parent(parent, lars, _G1575, _G1576) ;
  S = parent(parent, _G1574, lars, _G1576) ;
  S = parent(parent, _G1574, _G1575, lars).
  </code></pre>
  
  <p>I am giving up with this question, because the question was posed in the wrong way from the beginning. I should have asked more specifically - which I could not, because I am still no good in Prolog.</p>
  
  <p>@false helped me most. I am accepting his answer.</p>