# Define a relation for finding a list of pairs

**URL:** <https://swi-prolog.discourse.group/t/define-a-relation-for-finding-a-list-of-pairs/5923>\
**Category:** Help!\
**Created:** [November 8, 2022, 2:19pm UTC](https://swi-prolog.discourse.group/t/define-a-relation-for-finding-a-list-of-pairs/5923 "2022-11-08T14:19:04Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Owees](https://avatars.discourse-cdn.com/v4/letter/o/b19c9b/32.png) [@Owees](https://swi-prolog.discourse.group/u/Owees)\
**Post date:** [November 8, 2022, 2:19pm UTC](https://swi-prolog.discourse.group/t/define-a-relation-for-finding-a-list-of-pairs/5923/1 "2022-11-08T14:19:04Z")

</div>

Define the belongs(Pairs) relation for finding a list of pairs of the “figure”-“list of surrounding figures” type. (Consider that if there is facts contains(A, B), contains(B, C), then figure C belongs figure A)

Please help, this code does not output what it should

```prolog
figure(square1, red).
figure(circle, red).
figure(triangle, blue).
figure(rectangle, green).
figure(diamond, purple).
figure(square2, green).
figure(trapezium1, black).
figure(hexagon, grow).
figure(trapezium2, yellow).
figure(octagon, purple).
figure(trapezium3, red).

contains(square1, rectangle).
contains(circle, diamond).
contains(square1, hexagon).
contains(trapezium2, square2).
contains(trapezium1, triangle).
contains(triangle, square2).
contains(trapezium1, rectangle).
contains(octagon, trapezium3).
contains(rectangle, triangle).
contains(trapezium3, circle).
contains(trapezium3, square1).

figure_list(_) :- contains(A, B),
	(	retract(contains(A-C))
    -> M = C
    ; M = []
    ),
    assertz(contains(A-[B|M])),
    fail.
figure_list(List) :- extract_names(List).

belongs(Pairs) :-
    setof(Contains-Figure,
    	bagof(C, contains(Contains, C), Figure),
    	Pairs
	).

```

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [November 8, 2022, 7:22pm UTC](https://swi-prolog.discourse.group/t/define-a-relation-for-finding-a-list-of-pairs/5923/2 "2022-11-08T19:22:35Z")

</div>

The relational predicate belongs(Pair) should really be defined by Prolog rules without the use of assert and retract.

Using assert and retract is consider bad practice in prolog, unless one deals with extending (or changing) basic known facts – which is not the case in defining the relation above – where nothing new is asserted – by letting Prolog do a little bit of searching (by use of predicates), the knowledge of pair belonging is encoded in the known facts.

I guess, the way I would look to define it is in two steps:

Step 1: define an “atomic” belong for one pair only.

Step 2: define a predicate that would find all “atomic” ones and thereby construct the list.

Dan
