I am trying to intersect more lists in Scheme and I need a little help. The lists look like this:
The first two:
(((?x john) (?city new-york))
((?x mike) (?city chicago))
((?x mary) (?city london)))
and
(((?city chicago))
((?city new-york)))
I need to look in every list (say A) from the first list and see if there is a list (say B) in the second one so that A has at least one element in common with B. If there is no such element, the resulting list will not contain A. The result for the two lists mentioned above will be:
(((?x john) (?city new-york))
((?x mike) (?city chicago)))
since the list ((?x mary) (?city london))
has nothing in common with any list from (((?city chicago) ((?city new-york)))
.
Now the resulting list has to be intersected with the next list:
(((?x mike) (?game tennis))
((?x john) (?game air-hockey)))
The first list from the resulting list, ((?x john) (?city new-york))
will have (?x john)
in common with ((?x john) (?game air-hockey))
and therefore in my new resulting list the first list will look like this: ((?x john) (?city new-york) (?game air-hockey))
. Following this pattern with the second list, I will get ((?x mike) (?city chicago) (?game tennis))
and my new resulting list will be:
(((?x john) (?city new-york) (?game air-hockey))
((?x mike) (?city chicago) (?game tennis)))
This means that, for every two lists that have at least one element in common I have to do their reunion and add it to the new resulting list.
Now my question is, can you give me a little help in implementing this in Scheme? I don't want the code, only some ideas regarding which functions should I use :).
I understand that you have to solve this with lists, I won't write a list implementation because it'd be cumbersome (it's not the best data structure for the job), instead I'll show you how to solve the problem in terms of Racket's set operations, so you can translate it to use lists. First, a representation of the data:
With the representation in place, we need a procedure that given a single datum finds if it shares some element in common with a list of data - if it finds one match, it returns the union of data, if it doesn't find any it returns
#f
:For example:
Now it's easy to write a procedure that repeatedly matches all elements in one set of data with another set of data:
For instance, the first match between
s1
ands2
(as defined above) would look like this:To find successive matches among several sets of data just call
join
as many times as needed, with each set of data, accumulating the result:As you can see, the end result is the one we expected.
I'd start by improving your description.
(?x john)
is not alist
it is aquery
. And((?x john) (?city new-york))
is not a list of lists it is aproposition
(??). Andis not a list of list of lists it is a
set of propositions
.Once you start describing things unambiguously you can then start defining some operations on the entities: