简体   繁体   中英

Can Prolog make rules based on the facts available?

For example if there are facts of who likes which color and everyone likes green, but not everyone likes pink: likes(X, green) is true for all X, can Prolog somehow give a result that likes(X, green) is true for all X-es?

Lets say that there's also information about the gender of people within the rules in the form female(deby). male(robert). female(deby). male(robert). If according to the data set all females but not all males like pink, can Prolog return something like this: likes(X, pink) :-female(X)

Edit : When I say "I want to ask" in the last paragraph, I mean my query to Prolog should have this meaning.

To be clear I don't want to specify what Prolog should check. In English I don't want to ask, whether everyone likes green, but I want to ask: Can you make new rules based on the facts available?

facts:

male(albert).
male(brett).
female(chloe).
female(deby).

likes(albert, green).
likes(brett, green).
likes(chloe, green).
likes(deby, green).

likes(albert, pink).
likes(chloe, pink).
likes(deby, pink).

If you want to check if everyone likes green, then you just need to define what everyone means. Let's suppose it means "all the males and females". Then you could do this:

everyone_likes(Color) :-
    everyone(Everyone),
    all_likes(Everyone, Color).

everyone(Everyone) :-
    findall(E, (male(E) ; female(E)), Everyone).

all_likes([Person|People], Color) :-
    likes(Person, Color),
    all_likes(People, Color).
all_likes([], _).

Option 2

An alternative to the above is to think about the logic in the negative. If everyone likes green , that is the opposite of someone doesn't like green . Expressing that in Prolog:

everyone_likes(Color) :-
    is_color(Color),
    \+ (  (male(P) ; female(P)),
          \+ likes(P, Color)
       ).

Rather than having to define who everyone is in this version, we need an is_color fact and/or predicate which defines a valid color (if we want the everyone_likes(X) query to work). This could be define simply as:

is_color(pink).
is_color(green).
is_color(orange).
...

Or, you could define it as a predicate which derives the choices of color from other facts.

Yes, you can make new rules based on the facts available but I would suspect that it's very dependent on specific Prolog implementation. If you're working on SWI-Prolog, you can look at chapter 4.13 ("Database") in documentation and see how to use constructing predicates: assert/1, clause/2, clause/3 and others. It might be helpful to see description for copy_predicate_clauses/2.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM