1

I'm learning Prolog and this may be a very simple question.

Say I just need a procedure that does the following:

before(5, [1, 2, 4, 5, 36, 5], Result)
...
Result = [1, 2, 4, 5]

I'm aware that if N is the first element, I can add the following rule:

before(N, [N|_], Result) :- Result = [N].

But what should I do for the other cases?

coder
  • 12,832
  • 5
  • 39
  • 53
Henrique Dias
  • 182
  • 4
  • 13
  • In the other case, the second argument is a list `[X|Tail]` where `X` is also at the head of the overall result list. All that remains is to find (by recursion) the result list for the `Tail` list. – Isabelle Newbie Apr 07 '18 at 15:07
  • Thanks @IsabelleNewbie. Then I have `before(N, [X|Tail], Result)`. My idea was to add X to Result list until X was N, but for what I read I can't change a variable after defining it. Could you help with this? – Henrique Dias Apr 07 '18 at 15:20
  • 1
    If you have `[X|Tail]` and `N` is not `X`, then the result must be of the form `[X|ResultTail]`. – Isabelle Newbie Apr 07 '18 at 15:41
  • Thanks @IsabelleNewbie. Working now! – Henrique Dias Apr 07 '18 at 15:44
  • Simple solution would be: `before(N, L, Result) :- once(append(Result, [N|_], List)).` – lurker Apr 07 '18 at 15:52

1 Answers1

1

A very simple solution:

before( _, [], []).
before( N, [N|_], [N]).
before( N, [X|T], [X|Res]):- dif(N,X), before( N, T, Res).

Example:

?- before(5, [1, 2, 4, 5, 36, 5], Result).
Result = [1, 2, 4, 5] ;
false.

And a more elegant solution using if_/3 from library(reif):

:- use_module(library(reif)).

before( _, []   , [] ).
before( N, [X|T], Res):- 
            if_( X = N, 
                 Res = [N],
                 (before( N, T, Res2), Res = [X|Res2] )
               ).

Example:

?- before(5, [1, 2, 4, 5, 36, 5], Result).
Result = [1, 2, 4, 5].

As you can see this is deterministic it only gave one answer and no choice point left. In the first answer same result was given but there was a choice point returning false. This second answer which gives right result avoiding this useless choice point is more efficient. Also in

coder
  • 12,832
  • 5
  • 39
  • 53