title: Prolog puzzle with given Knowledge Base - Not Working
body: <p>I know the title of the topic exists here: <a href="https://stackoverflow.com/questions/13305356/a-prolog-program-that-reflects-people-sitting-at-a-round-table">A prolog program that reflects people sitting at a round table</a></p>
  
  <p>But I need a different solution, more simple.</p>
  
  <p>So I have this problem where 4 people sit around a square table.</p>
  
  <p>We know their names.
  And that someone is the orthopedist, someone the dentist, someone the surgeon and someone the pediatrician.</p>
  
  <p>We have a knowledge base that you will see in the code.</p>
  
  <p>And we have to find what is the name of the pediatrician.</p>
  
  <p>My program finds it, but doesn't print all four possible combinations for the list that represents the seats on the table.</p>
  
  <pre><code>table(List):-
      length(List,4),
      member(convive(argiro,_,female),List),
      member(convive(georgia,_,female),List),
      member(convive(basilis,_,male),List),
      member(convive(dimitris,_,male),List),
      left(convive(_,dentist,_),convive(argiro,_,female),List),
      oppo(convive(_,surgeon,_),convive(basilis,_,male),List),
      next(convive(georgia,_,female),convive(dimitris,_,male),List),
      left(convive(_,_,female),convive(_,orthopedist,_),List),
      member(convive(_,pediatrecian,_),List).
  
  left(X,Y,ConLs):-append(_,[X,Y|_],ConLs).
  
  left(X,Y,ConLs):-prefix(X,ConLs),last(ConLs,Y).
  
  next(X,Y,ConLs):-left(X,Y,ConLs).
  
  next(X,Y,ConLs):-append(_,[Y,X|_],ConLs).
  
  next(X,Y,ConLs):-prefix(Y,ConLs),last(ConLs,X).
  
  oppo(X,Y,ConLs):-next(X,Z,ConLs),next(Z,Y,ConLs),X\==Y.
  </code></pre>
  
  <p>On the terminal I get:</p>
  
  <blockquote>
    <p>?- table(List),member(convive(Name,pediatrecian,_),List).</p>
    
    <p>List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
    Name = argiro ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
    Name = argiro ;</p>
    
    <p>false.</p>
  </blockquote>
  
  <p>So as you can see, I get the name, but only the 2 possible lists representing where each person is seated. There should also be:</p>
  
  <blockquote>
    <p>List = [convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female)]</p>
    
    <p>List = [convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male)]</p>
  </blockquote>
  
  <p>I have used the lines</p>
  
  <pre><code>left(X,Y,ConLs):-prefix(X,ConLs),last(ConLs,Y).
  
  next(X,Y,ConLs):-prefix(Y,ConLs),last(ConLs,X).
  </code></pre>
  
  <p>But, they are not doing anything, if I erase them, I get the same result.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <pre><code>table(List):-
  length(List,4),
  member(convive(argiro,_,female),List),
  member(convive(georgia,_,female),List),
  member(convive(basilis,_,male),List),
  member(convive(dimitris,_,male),List),
  left(convive(_,dentist,_),convive(argiro,_,female),List),
  oppo(convive(_,surgeon,_),convive(basilis,_,male),List),
  next(convive(georgia,_,female),convive(dimitris,_,male),List),
  left(convive(_,_,female),convive(_,orthopedist,_),List),
  member(convive(_,pediatrecian,_),List).
  
  left(X,Y,ConLs):-append(_,[X,Y|_],ConLs).
  
  left(X,Y,ConLs):-prefix(X,ConLs),last(ConLs,Y).
  
  next(X,Y,ConLs):-left(X,Y,ConLs);left(Y,X,ConLs).
  
  %next(X,Y,ConLs):-append(_,[Y,X|_],ConLs).
  
  next(X,Y,ConLs):-prefix(Y,ConLs),last(ConLs,X).
  
  %oppo(X,Y,ConLs):-next(X,Z,ConLs),next(Z,Y,ConLs),X\==Y.
  
  oppo(X,Y,[X,_,Y,_]).
  
  oppo(X,Y,[Y,_,X,_]).
  
  oppo(X,Y,[_,X,_,Y]).
  
  oppo(X,Y,[_,Y,_,X]).
  </code></pre>
  
  <p>So, oppo/3 seems to be working fine on the given lists</p>
  
  <blockquote>
    <p>?- table(List), <strong>oppo</strong>(convive(argiro,pediatrecian,female),Name,List).</p>
    
    <p>List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],</p>
    
    <p>Name = convive(dimitris, orthopedist, male) ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = convive(dimitris, orthopedist, male) ;</p>
    
    <p>false.</p>
  </blockquote>
  
  <hr>
  
  <p>left/3 seems to be doing the same thing that I'm trying to solve in the first place, it works in the list where argiro is number 2 and georgia is 3 which is a simple case, <strong>but in the second list that you can see above in oppo/3 results, where argiro is number 4 and georgia is number 1, it should see that georgia is again on the left of argiro but doesn't.</strong></p>
  
  <blockquote>
    <p>?- table(List), <strong>left</strong>(convive(argiro,pediatrecian,female),Name,List).</p>
    
    <p>List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],</p>
    
    <p>Name = convive(georgia, surgeon, female) ;</p>
    
    <p>false.</p>
  </blockquote>
  
  <hr>
  
  <p>Now next/3 returns some pretty disturbing results. I don't know what to make of this, I'm a newbie in Prolog. Some are okay, but some seem to be taking whole arrays as results, some say List = Name.</p>
  
  <p>The first three results are ok, and <strong>the fourth is doing the same as left/3, it can't see that the first one in the list is next to the last one so it returns an empty array.</strong></p>
  
  <p>What is happening here?</p>
  
  <blockquote>
    <p>?- table(List), <strong>next</strong>(convive(argiro,pediatrecian,female),Name,List).</p>
    
    <p>List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],</p>
    
    <p>Name = convive(georgia, surgeon, female) ;</p>
    
    <p>List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],</p>
    
    <p>Name = convive(basilis, dentist, male) ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = convive(basilis, dentist, male) ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = [] ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = [convive(georgia, surgeon, female)] ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)] ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male)] ;</p>
    
    <p>List = Name,</p>
    
    <p>Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)] ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = [] ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = [convive(georgia, surgeon, female)] ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)] ;</p>
    
    <p>List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],</p>
    
    <p>Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male)] ;</p>
    
    <p>List = Name, </p>
    
    <p>Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)] ;</p>
    
    <p>false.</p>
  </blockquote>
  
  <p><strong>UPDATE</strong></p>
  
  <p>So I learned that prefix/2 works with strings, for example,
  <code>prefix(x,[x,y,z]).</code> returns false.
  That's why it's not working, and that explains the results in next/3, but still my problem isn't solved.</p>
  
  <p>Any other way to make left and next work with the first and last part of the list?</p>