Search code examples
listsearchprologpredicate

How to look up a value inside a list in a predicate, in PROLOG


So far I've done my fair amount of research and I've tried different methods, however even after reading multiple stack overflow answers and even a PDF from Addison Wesley, I can't find the way to do it. Here is the code

use_module(library(func)).
% importing library "func"

scale([c, d, e, f, g, a, b]).
scale(c, major, [c, d, e, f, g, a, b]).
scale(c, minor, [c, d, e_b, f, g, a_b, b_b]).

%1st attempt 
search(note, scale):- scale(note, scale).

%2nd attempt
scaleOf(note, type_scale):- scale(note, type_scale).

on(item,[item|rest]).  

on(item,[disregardHead|tail]):-
    scale(tail),
    on(item, tail).

%3rd attempt 

fatherOf(father,type, son):- scale(father, type, sons), search(son, type, sons).
search(son, type, []):- !, fail.
search(son, type, [son|l]):- !, true.
search(son, type, [c|l]):- search(son, type, l).

What am I attempting? Simple, something that can iterate through the predicate scale(c, [c, d, e, f, g, a, b]). But I can't get it right.

Edit: I have multiple predicates because someone else suggested creating a predicate that would differentiate one scale from the other. I thought I could cram it inside any algorithm but I guess PROLOG is not that lenient :p


Solution

  • You can do that with member/2 [swi-doc]. This can be used to search, unify with a member, or generate a list.

    So you can search with:

    search(Note, Scale, Item) :-
        scale(Note, Scale, Items),
        member(Item, Items).

    It is important that Note, Scale, Item and Items start with an Uppercase, since identifiers with a lower case are constants or functors. Identifiers with an uppercase are variables.

    This will thus unify Item with the items in the list, for the given sample data we for example obtain:

    ?- search(c, minor, Item).
    Item = c ;
    Item = d ;
    Item = e_b ;
    Item = f ;
    Item = g ;
    Item = a_b ;
    Item = b_b.