I want to write a predicate that takes a member of a tuple, that tuple, and outputs the other member of the tuple. You may assume tuples always have 2 elements, and the supplied member is always present.
extract_from_tuple(_, [], _).
extract_from_tuple(X, [H|T], R) :-
( X \= H -> R is X, ! ; X = H -> extract_from_tuple(X, T, R) ).
I tried to implement a simple if-else statement syntax I found on How to write IF ELSE conditions in Prolog.
So for example,
extract_from_tuple(a, [b,a], R).
should output b
in the result variable R
Same should be for other way around:
extract_from_tuple(a, [a,b], R).
Only this time it 'should' hit the else statement and recursively call the predicate with the other element of the supplying list.
CodePudding user response:
I think this problem is very simple and can be solved using just unification:
extract(X, [X,Y], Y).
extract(Y, [X,Y], X).
Examples:
?- extract(a, [b,a], R).
R = b.
?- extract(a, [a,b], R).
R = b ;
false.
To avoid spurious choice point, you can code extract/3
as:
extract_deterministic(Item, [First,Second], Rest) :-
( Item = First
-> Rest = Second
; Rest = First ).
Notice, however, this last version is less general than the first one! For example:
?- extract(X, [a,b], R). % two answers!
X = a,
R = b ;
X = b,
R = a.
?- extract_deterministic(X, [a,b], R). % only one answer!
X = a,
R = b.