1

I have the following problem.

I'm given a listOfLists, a value (row,col) and I need to get the list inside a list that contains that certain value, up to my value's index inside that list.

For example

?- find_list([[(1,2),(1,3),(1,4)], [(2,2),(2,3),(2,4)]], (1,3), List2).
List2 = [(1,2),(1,3)].

My problem is that if I use member/2 I will only get true or false for if my value is inside listOfList or not, and not the list that I will need to be working with.

How can I get that list that has my value inside it?

false
  • 10,264
  • 13
  • 101
  • 209
Big Bear
  • 21
  • 3
  • 1
    Your example result of `[(1,2),(1,3)]` is not a member of your list of lists, so I don't understand it. As far as the answer to your question, you need to write a recursive predicate that checks each member of your lists of lists using `member/2`. It's a very basic example of Prolog list recursion. For example, `find_list([List|Lists], Element, List) :- member(Element, List).` succeeds if `Element` is a member of the first list in the given list of lists. You should try completing the rest of that logic. – lurker May 03 '18 at 13:01
  • This probably a duplicate of: [Does an element exists in a list of lists](https://stackoverflow.com/questions/43414936/does-an-element-exists-in-a-list-of-lists) – lurker May 03 '18 at 13:05
  • @lurker If the (row,column) that I'm looking for is inside a list of lists, I need to "print" that list that contains (row,column), up to my (row,column), so, for example, if the lists only contained integers, and I had a list containing [1,9,2,3,4,10,6] and the value I had to check for was 3, I would need my List2 to be = [1,9,2,3]. Did I make it clear now? Instead of integers, I have a (value1,value2) type to look for – Big Bear May 03 '18 at 13:22
  • @lurker plus, I don't want to return True or False, I want to return L2 when I find my value inside any list of listOfLists, with L2 being that list that contains my value, from the start of it till the index that contains my value – Big Bear May 03 '18 at 13:48
  • "returning" true or false is fundamentally how Prolog predicates work. It's not a choice of returning true, false, or something else. A predicate seeks a solution and, if it finds one, it succeeds (shows "true" on the console) and if it does not find one it fails (shows "false" on the console). They actually do not "return" a true/false value. They succeed or they fail. You want it to succeed with your solution. – lurker May 03 '18 at 16:01

1 Answers1

2

Does it matter that the values are two-dimensional coordinates? Is there an ordering on them that you must respect, or is it simply the ordering of the elements in the list? I will assume the latter.

If you want to split a list at some point, the standard append/3 predicate is usually the way to go. For example, assume we want to cut the list [a, b, c, d, e] into a prefix containing the elements before c and a suffix containing the elements after c. Here is how that is done:

?- append(Prefix, [c | Suffix], [a, b, c, d, e]).
Prefix = [a, b],
Suffix = [d, e] ;
false.

Here c is excluded from the prefix, but that's easy to fix:

?- append(Prefix, [c | Suffix], [a, b, c, d, e]), append(Prefix, [c], UpToAndIncludingC).
Prefix = [a, b],
Suffix = [d, e],
UpToAndIncludingC = [a, b, c] ;
false.

We can give this predicate a nice name:

list_pivot_prefix(List, Pivot, Prefix) :-
    append(Prefix0, [Pivot | _Suffix], List),
    append(Prefix0, [Pivot], Prefix).

And your find_list/3 predicate then simply finds all the lists in the given list of lists for which this relation holds:

find_list(Lists, Element, Prefix) :-
    member(List, Lists),
    list_pivot_prefix(List, Element, Prefix).

Here is your test case:

?- find_list([[(1,2),(1,3),(1,4)],[(2,2),(2,3),(2,4)]],(1,3),List2).
List2 = [ (1, 2), (1, 3)] ;
false.
Isabelle Newbie
  • 9,258
  • 1
  • 20
  • 32