<h1>Declarative wording</h1>

<p>Almost always, when a Prolog task is formulated in a rather <em>imperative</em> way, the solution will be comparatively limited. This means that we typically can only use it in a few modes and directions, while other modes may even yield wrong results.</p>

<p>Therefore, I suggest to use more <em>declarative</em> wording.</p>

<p>You say:</p>

<blockquote>
  <p>a predicate that <strong>takes</strong> a list and <strong>succeeds</strong> if the list <strong>contains</strong> elements "a, b, c" in that order anywhere in the list, otherwise it <strong>fails</strong>.</p>
</blockquote>

<p>That's a rather <em>procedural</em> way to look at this. Note that in Prolog, any argument can also be a logical <em>variable</em>, and thus there may not even be a list to "take". Instead, we expect the predicate to <strong>generate</strong> such lists in these cases!</p>

<p>Watch your wording! Very often, when you are able to express the task <em>declaratively</em>, an elegant and general Prolog solution will be straight-forward and often follows quite naturally from the task description.</p>

<h1>Describing solutions</h1>

<p>First, let us focus on <strong>what holds</strong>. There is no need to express what <em>doesn't hold</em>, because the predicate <em>will not succeed</em> anyways in such cases.</p>

<p>What do we want to <em>describe</em>?</p>

<p>Essentially, we want to <em>describe</em> lists of the form <code>[...,a,b,c,...]</code>.</p>

<p>There are already some answers, with various drawbacks.</p>

<p>A <strong>pure</strong> way to do it uses the meta-predicate <code>if_/3</code> from <a href="https://arxiv.org/abs/1607.01590" rel="nofollow noreferrer"><em>Indexing&nbsp;dif/2</em></a>:</p>

<pre>
abc([X,Y,Z|Vs]) :-
        if_((X=a,Y=b,Z=c), true, abc([Y,Z|Vs])).
</pre>

<h1>Generality</h1>

<p>This works in all directions. First, let us try the <strong>most general</strong> query, where the single argument is a fresh <em>variable</em>:</p>

<pre>
<b>?- abc(Vs).</b>
Vs = [a, b, c|_5032] ;
Vs = [a, b, a, b, c|_5144] ;
Vs = [a, b, a, b, a, b, c|_5286] .
</pre>

<p>Thus, we can <em>generate</em> solutions, which is a very nice property of a relation!</p>

<p>The predicate is <em>monotonic</em>, and therefore <em>iterative deepening</em> is possible to <em>fairly</em> enumerate answers:</p>

<pre>
<b>?- length(Vs, _), abc(Vs).</b>
Vs = [a, b, c] ;
Vs = [a, b, c, _11600] ;
Vs = [a, a, b, c] ;
Vs = [_11982, a, b, c],
dif(_11982, a) ;
Vs = [a, b, c, _11600, _11606] .
</pre>

<p>From this, it follows that there are <em>no solutions</em> with less than 3&nbsp;elements. In this case, that's quite obvious. In other cases, such results may be much less obvious from the task description.</p>

<h1>Efficiency</h1>

<p>The predicate is <strong>deterministic</strong> if its argument is sufficiently instantiated.</p>

<p>For example:</p>

<pre>
?- abc([a,b,c]).
<b>true.</b>

?- abc([z,a,b,c]).
<b>true.</b>

?- abc([a,b,c,z]).
<b>true.</b>
</pre>

<p>Note that <em>no choice points</em> remain in these cases!</p>
Finding a specific sequence of elements in a list, prolog
<p>I have to write a predicate that takes a List and succeeds if the list contains elements "a, b, c"in that order anywhere in the list, other wise it fails. I am pretty lost on where to start(not looking for a solution, just a hint to the right direction).</p>