# Logically pure/impure predicate implementations in the std lib

**URL:** <https://swi-prolog.discourse.group/t/logically-pure-impure-predicate-implementations-in-the-std-lib/6317>\
**Category:** General\
**Created:** [February 28, 2023, 6:39am UTC](https://swi-prolog.discourse.group/t/logically-pure-impure-predicate-implementations-in-the-std-lib/6317 "2023-02-28T06:39:02Z")\
**Posts on this page:** 1\
**Showing post:** 16

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [March 1, 2023, 4:05am UTC](https://swi-prolog.discourse.group/t/logically-pure-impure-predicate-implementations-in-the-std-lib/6317/16 "2023-03-01T04:05:15Z")

</div>

> [@anon95304481](#):
>
> [dif/2](https://www.swi-prolog.org/pldoc/doc_for?object=dif/2) to the rescue!

And we don’t need clp(fd); freeze/2 and when/2 work just fine:

```prolog
runs(R, L) :- phrase(runs(_, L), R).
% runs(X, R, L) :- phrase(runs(X, L), R).

runs(X, [X-N|R]) --> {freeze(N, N > 0)}, run(X, N), {dif(X,Y)}, runs(Y, R).
runs(_, []) --> [].

run(X, N) --> {freeze(N, N > 0)}, {when_plus1(M, N)}, [X], run(X, M).
run(_, 0) --> [].

when_plus1(A,C) :-
    when((nonvar(A);nonvar(C)), plus(A,1,C)).

```

```prolog
?- runs([a, a, b, c, c, c], L).
L = [a-2, b-1, c-3] ;
false.

?- runs(L, [a-2, b-1, c-3]).
L = [a, a, b, c, c, c] ;
false.

```

---

_[View the full topic](https://swi-prolog.discourse.group/t/logically-pure-impure-predicate-implementations-in-the-std-lib/6317)._
