-
I wrote the following rule which relates a list and a predicate to the first element in the list that satisfies the predicate. list_pred_first([], _, []).
list_pred_first([H|T], Pred, Element) :-
Goal =.. [Pred, H],
( call(Goal) ->
Element = H
; list_pred_first(T, Pred, Element)
). On advice from @triska I would like to remove use of the list_pred_first([], _, []).
list_pred_first([H|_], Pred, H) :-
Goal =.. [Pred, H],
call(Goal).
list_pred_first([H|T], Pred, Element) :-
Goal =.. [Pred, H],
\+ call(Goal),
list_pred_first(T, Pred, Element). As a side question, how do you feel about the name of the rule? |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 15 replies
-
The https://www.complang.tuwien.ac.at/ulrich/papers/PDF/indexingdif2.pdf paper has a lot of great material in there relevant to this, and you can see how it implements some of the higher-order monotonic relations like tfilter and so on. Maybe in this case, if you use list_pred_first([H|T], Pred, R) :-
if_(call(Pred, H), R = H, list_pred_first(T, Pred, R)). here is some example usages: ?- list_pred_first([1,1,2,3,4], dif(2), R).
R = 1.
?- list_pred_first([1,1,2,3,4], dif(1), R).
R = 2.
?- list_pred_first([], dif(1), R).
false. |
Beta Was this translation helpful? Give feedback.
-
Using =(1) gives general answers:
|
Beta Was this translation helpful? Give feedback.
-
I was hoping this general query would have given answers, where a list element was different to 1.
but seemingly it does not terminate. |
Beta Was this translation helpful? Give feedback.
-
Unrelated to your main question, and as seen in @david-sitsky code, learn (also) about the |
Beta Was this translation helpful? Give feedback.
-
On a general note, p(a). Then we get: ?- list_pred_first(Ls, p, F). Ls = [], F = [] ; Ls = [a|_A], F = a ; false, unexpected, incomplete. A nice overview of pure monotonic predicates was recently posted in other discussions, the link is: https://old.reddit.com/r/prolog/comments/10nuwz8/what_exactly_is_the_pure_monotonic_core_of_prolog/ To benefit most from Prolog, I recommend to keep to this pure core, where you can benefit from strong logical properties that are useful for debugging and reasoning about your code. |
Beta Was this translation helpful? Give feedback.
-
I'd like to clear up a possible misunderstanding I have with It was suggested that I can implement my list_pred_first([], _, []).
list_pred_first([H|T], Pred, R) :-
if_(call(Pred, H), R = H, list_pred_first(T, Pred, R)). But when I test it like this: L = [foo, Bar, baz],
list_pred_first(L, var, FirstVar). expecting to get |
Beta Was this translation helpful? Give feedback.
-
You need to reify
But note Ulrich's observations on |
Beta Was this translation helpful? Give feedback.
-
Yes, |
Beta Was this translation helpful? Give feedback.
You need to reify
var/1
:But note Ulrich's observations on
var/1
...