HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Harry Potter's Family Tree Database

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
harrydatabasefamilypottertree

Problem

As an assignment for a class, I have made a small Harry Potter family tree in Prolog. It compiles into a self-contained executable that can be run straight from the command line on Linux machines. This is my second ever program in Prolog, so I am still learning. My background is in imperative languages, so I am probably doing things and formatting my code in a not very "Prolog-ish" manner.

Main

:- [pft].

print_query_true(Q) :-
    forall(Q, writeln(true:Q)).

print_query_false(Q) :-
    forall(\+ Q, (writeln(false:Q), nl)).

get_input :- 
    writeln('Enter "1." to run a query or "9." to exit:'), 
    read(I), 
    (
        I = 1 -> run_query;
        I = 9 -> writeln('Goodbye'), halt;
        writeln('Invalid input!')
    ).

run_query :- 
    writeln('Enter your query, followed by a period (.):'), 
    read(I),
    nl,
    print_query_true(I),
    print_query_false(I),
    nl.

main :- repeat, get_input, fail.


PFT

```
%male(X)
male(fleamont).
male(james).
male(harry).
male(albus).
male(james_ii).
male(arthur).
male(bill).
male(charlie).
male(percy).
male(george).
male(fred).
male(ron).
male(hugo).
male(mr_granger).

%female(X)
female(euphemia).
female(lily).
female(ginny).
female(lily_ii).
female(molly).
female(mrs_granger).
female(hermione).
female(rose).

%parent(Parent, Child)
parent(fleamont, james).
parent(euphemia, james).
parent(james, harry).
parent(lily, harry).
parent(harry, albus).
parent(harry, james_ii).
parent(harry, lily_ii).
parent(ginny, albus).
parent(ginny, james_ii).
parent(ginny, lily_ii).
parent(arthur, bill).
parent(arthur, charlie).
parent(arthur, percy).
parent(arthur, fred).
parent(arthur, george).
parent(arthur, ron).
parent(arthur, ginny).
parent(molly, bill).
parent(molly, charlie).
parent(molly, percy).
parent(molly, fred).
parent(molly, george).
parent(molly, ron).
parent(molly, ginny).
parent(ron, rose).
parent(ron, hugo).
parent(hermione, rose).
parent(hermione, hugo).
parent(mr_granger, hermione).
parent(mrs_granger,

Solution

Your closest_common_ancestor/3 doesn't work, for instance, closest_common_ancestor(rose, fred, X). fails to find answers, however X=arthur and X=molly are both answers.

Below is the version that would work:

closest_common_ancestor(P1, P2, CCA) :-
    parent(CCA, P1),
    parent(CCA, P2).
closest_common_ancestor(P1, P2, CCA) :-
    parent(P, P1),
    closest_common_ancestor(P, P2, CCA).
closest_common_ancestor(P1, P2, CCA) :-
    parent(P, P2),
    closest_common_ancestor(P1, P, CCA).


Some general advise:

  • There's no reason not to name variables in predicates the way you described them in the documentation. In fact, I'd prefer Person1 to P1, especially in the context where Parent1 could be also inferred. Also, there are some documentation tools, usually bundled with whatever version of Prolog you are using, that have certain conventions wrt documentation format. If you wanted to produce documentation that is usable for others in an automatic way, it would help to study those tools. For example, if you are using swipl, look at http://www.swi-prolog.org/pldoc/doc_for?object=section(%27packages/pldoc.html%27) .



  • Try avoiding expressing your assertions through negation. It is an art in and for itself, but once you start following this rule, you'll realize that the code you produce is more straight-forward and less verbose. It takes, however, time and effort to adopt this rule.



  • Use format instead of print, nl and friends. Unless you are writing some utility code whose purpose is printing, there's no reason to clutter the code with string formatting.

Code Snippets

closest_common_ancestor(P1, P2, CCA) :-
    parent(CCA, P1),
    parent(CCA, P2).
closest_common_ancestor(P1, P2, CCA) :-
    parent(P, P1),
    closest_common_ancestor(P, P2, CCA).
closest_common_ancestor(P1, P2, CCA) :-
    parent(P, P2),
    closest_common_ancestor(P1, P, CCA).

Context

StackExchange Code Review Q#142539, answer score: 2

Revisions (0)

No revisions yet.