0

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.

GeorgeR
  • 149
  • 9
  • In addition to the accepted answer: Never use notation like `[a, b]` for tuples. This is list notation. You will just get confused if you don't make a clear distinction between lists and tuples. Common ways of writing such pairs would be `(a, b)`, `a-b`, or `pair(a, b)`. – Isabelle Newbie Nov 28 '21 at 16:00

1 Answers1

1

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.
slago
  • 5,025
  • 2
  • 10
  • 23