Steven Soult
Steven Soult

Reputation: 3

Prolog - I have a specific fact format I need to match

Okay, so basically my teacher gave us a specific format for facts:

m([first_male_name, second_male_name,...,last_male_name]).
f([first_female_name,...last_female_name).
family([father,mother,[child1,...,childn]]).

and I can't figure out how to get my code to interpret the facts correctly. I've tried a few different ways, but I think there is just something fundamentally wrong with my understanding of this. This is the part of my code relating to the issue:

male(X) :- m(Males), member(X, Males).
female(X) :- f(Females), member(X, Females).
parent(X,Y) :- (family([X,_,Child]); family([_,X,Child])), member(Y,Child).

m(['David', 'Lance', 'Charles', 'George', 'Henry', 'Jose', 'Lenny', 'Vance', 'Rhett', 'Jacob', 'Mike']).
f(['Sarah', 'Tammy', 'Jasmine', 'Cassondra', 'Kat', 'Laura', 'Tamarah', 'Nina', 'Stephanie', 'Christen', 'Shannon', 'Maryalice']).
family(['David', 'Sarah', ['George', 'Kat']]).

but when I try ?- male(Jose). it returns Jose = 'David'. Anyone have some insight into what's wrong? I'd really appreciate the help.

Edit: Thanks for the help. I guess it was just a simple mistake, but I doubt I would have realized it without help. I've got it working now.

Upvotes: 0

Views: 309

Answers (2)

lurker
lurker

Reputation: 58274

This is an answer to a question you didn't ask, so really should be a comment. But it's way to long for a comment. :)

In Prolog, for program organization, flexibility, and efficiency, it's best to assert your facts as individual facts, not as conglomerated lists. For example, in your case for m you have:

m([first_male_name, second_male_name,...,last_male_name]).

As in other languages, it's also best to give your facts, predicates, and variables sensible names. So let's rename this one:

males([first_male_name, second_male_name,...,last_male_name]).

Let's suppose you have a predicate which has a condition that PersonName is an male. With the above fact, here's how it might be done:

some_predicate(...) :-
    ...
    males(ListOfMales),
    member(PersonName, ListOfMales),
    ...

Instead, you should use individual facts:

male(first_male_name).
male(second_male_name).
...

Then your predicate becomes:

some_predicate(...) :-
    ...
    male(PersonName),
    ...

You don't even need the predicate male/1 that you have now. Similarly for female/1.

For family, each relationship should be its own fact. Rather than define a single, complex fact with lists to define a family like this:

family([father,mother,[child1,...,childn]]).

A more common way to define this would be:

parents_child(father, mother, child1).
parents_child(father, mother, child2).
...

Then parent(X, Y) becomes:

parent(X, Y) :-
    parents_child(_, X, Y) ; parents_child(X, _, Y).

Or even, for the most flexibility (e.g., what if it's a broken family, or parents were remarried, etc):

father_child(father, child1). father_child(father, child2). ... mother_child(mother, child1). mother_child(mother, child2). ...

Then you have:

parent(X, Y) :-
    father_child(X, Y) ; mother_child(X, Y).

Upvotes: 1

user7473772
user7473772

Reputation:

Prolog "variables" start with capital letter. If you want to make them "literals" which is atoms you put them in single quotes.

I found it useful to use in SWI-Prolog char_type to learn the exact rules (for SWI-Prolog I guess)... You can use prolog_var_start "start a Prolog variable name" or prolog_atom_start "start a unquoted Prolog atom that is not a symbol"

?- bagof(C, char_type(C, prolog_var_start), Cs) ; true.
Cs = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'|...] [write]
Cs = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ'] ;
true.

?- bagof(C, char_type(C, prolog_atom_start), Cs).
Cs = [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, ª, µ, º, ß, à, á, â, ã, ä, å, æ, ç, è, é, ê, ë, ì, í, î, ï, ð, ñ, ò, ó, ô, õ, ö, ø, ù, ú, û, ü, ý, þ, ÿ].

Upvotes: 0

Related Questions