1
votes

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). 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).
2
No, Prolog doesn't guess about your DB. Seems you need to search for 'ILP Prolog' and filter out among thousands of related resources... - CapelliC
I'm not quite sure what you're asking. Early in your post, you said, ...can Prolog somehow give a result that likes(X, green) is true for all X-es?, but then you later say, I don't want to ask, whether everyone likes green, which seems to contradict the first question. The answer to the question, Can you make new rules based on the facts available? is "yes" if you make those rules yourself. That's what Prolog is about. But are you looking for some kind of automatic rule generation? If that were the case, then you'd need meta-rules to describe what a valid rule looks like. - lurker
Yes, I'm looking for automatic rule generation. The idea is that in a bigger database I would not myself recognise patterns like everyone likes green, it would take too much time to write a query about all the possible patterns. I want Prolog to create the rules "everyone likes green" and "females like pink" without me making a query about each of those rules explicitly. Both of those rules should come up as a result to a single query. - user3546630
It sounds like you want some "meta rules" to generate rules, which would be possible. But you'd need to write the meta rules. Then, per the answer given by @g_a_kowalski, you can use assert/1, etc, to manage dynamic rules. - lurker
I hoped that there would be an easier way, however if I want to make meta-rules instead of the usual likes(X, green), which only asks if anybody likes green I need, a different query which asks if everyone likes green. Is that possible? - user3546630

2 Answers

2
votes

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.

0
votes

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.