3 ms·
To illustrate how close Erlang syntax is to Prolog, here is drop/3 in Prolog: drop(X, List, Result) :- drop(X, List, [], Result). drop(_, [], Acc, Res
by triska 9y ago
To illustrate how close Erlang syntax is to Prolog, here is drop/3 in Prolog:
drop(X, List, Result) :- drop(X, List, [], Result).
drop(_, [], Acc, Result) :- reverse(Acc, Result).
drop(X, [X|Rest], Acc, Result) :- drop(X, Rest, Acc, Result).
drop(X, [Y|Rest], Acc, Result) :- dif(X, Y), drop(X, Rest, [Y|Acc], Result).
I only had to make a few syntactic changes to the original program to obtain a Prolog predicate from it. The most significant change is that I use an additional argument to hold the original function's return value. An important consequence of the resulting relational nature is that this can answer quite general queries.
For example, we can ask: What are possible solutions Ls that arise when we drop X from the single-element list [A] ?
?- drop(X, [A], Ls).
X = A, Ls = [] ;
dif(X, A), Ls = [A].
We see that there are two possible answers: One where X is A, and hence the result is the empty list []. And the other where X is different from A, as indicated by dif(X, A).
Even more generally, we can systematically enumerate all conceivable solutions for all list lengths:
?- length(Ls0, _), drop(X, Ls0, Ls).
Ls0 = Ls, Ls = [] ;
Ls0 = [X],
Ls = [] ;
Ls0 = Ls, Ls = [_586],
dif(X, _586) ;
Ls0 = [X, X],
Ls = [] ;
Ls0 = [X, _598],
Ls = [_598],
dif(X, _598) ;
etc.
This uses iterative deepening to generate all possible answers.
- kqr 9y agoAlso not stuck using only an unbound result. Could we not ask "given L and Ls, what elements were dropped?"
- triska 9y agoYes, that's also possible with this definition! For example: Given Ls0 = [a,b,c] and Ls = [a,c], which element (if any) was dropped: ?- drop(X, [a,b,c], [a,c]). X = b ; false. As another example, if both Ls0 and Ls are [a,b,c]: ?- drop(X, [a,b,c], [a,b,c]). dif(X, c), dif(X, b), dif(X, a). This means that X must be different from each of these elements. More generally, which elements can be dropped at all from the list [a,b,c]: ?- drop(X, [a,b,c], _). X = a ; X = b ; X = c ; dif(X, c), dif(X, b), dif(X, a). Interestingly, the predicate definition does not even use "=" in its clauses. In Prolog, (=)/2 is a built-in predicate that means unification. In the definition above, we use implicit unification instead of explicit unification.