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, hermione).%married(Husband, Wife)married(fleamont, euphemia).married(james, lily).married(harry, ginny).married(arthur, molly).married(ron, hermione).married(mr_granger, mrs_granger).%spouse(X, Y)spouse(X,Y) :- married(X, Y); married(Y, X).%father(Father, Child)father(F, C) :- parent(F, C), male(F).%mother(Mother, Child)mother(M, C) :- parent(M, C), female(M).%brother(Brother, Person In Question)brother(B, PIQ) :- male(B), sibling(B, PIQ).%sister(Sister, Person In Question)sister(S, PIQ) :- female(S), sibling(S, PIQ).%child(Child, Parent)child(C, P) :- parent(P, C).%son(Son, Parent)son(S, P) :- child(S, P), male(S).%daughter(Daughter, Parent)daughter(D, P) :- child(D, P), female(D).%grandchild(Grandchild, Grandparent)grandchild(GC, GP) :- child(GC, P), child(P, GP).%grandson(Grandson, Grandparent)grandson(GS, GP) :- grandchild(GS, GP), male(GS).%granddaughter(Granddaughter, Grandparent)granddaughter(GD, GP) :- grandchild(GD, GP), female(GD).%sibling(X, Y)sibling(X, Y) :- parent(P, X), parent(P, Y), X \= Y.%grandparent(Grandparent, Grandchild)grandparent(GP, GC) :- grandchild(GC, GP).%grandfather(Grandfather, Grandchild)grandfather(GF, GC) :- male(GF), grandparent(GF, GC).%grandmother(Grandmother, Grandchild)grandmother(GM, GC) :- female(GM), grandparent(GM, GC).%brother_in_law(Spouses Brother, Person In Question)brother-in-law(SB, PIQ) :- brother(SB, Spouse), spouse(PIQ, Spouse).%sister_in_law(Spouses Sister, Person In Question)sister-in-law(SS, PIQ) :- sister(SS, Spouse), spouse(PIQ, Spouse).%aunt(Aunt, Person In Question)aunt(A, PIQ) :- sister(A, P), parent(P, PIQ).%uncle(Uncle, Person In Question)uncle(U, PIQ) :- brother(U, P), parent(P, PIQ).%niece(Niece, Person In Question)niece(N, PIQ) :- daughter(N, P), sibling(P, PIQ).%nephew(Nephew, Person In Question)nephew(N, PIQ) :- son(N, P), sibling(P, PIQ).%descendant(Descendant, Ancestor)descendant(D, A) :- parent(A, D).descendant(D, A) :- parent(P, D), descendant(P, A).%ancestor(Ancestor, Descendant)ancestor(A, D) :- descendant(D, A).%closest_common_ancestor(Person1, Person2, Closest Common Ancestor)closest_common_ancestor(P1, P2, CCA) :-     ancestor(CCA, P1),     ancestor(CCA, P2),    forall(child(C, CCA), (not(ancestor(C, P1)), not(ancestor(C, P2)))),    P1 \= P2.%write_descendant_chain(Descendant, Ancestor)write_descendant_chain(D, A) :-     (         child(D, A) -> write_child(D, A);         child(D, P),             descendant(P, A),             write_child(D, P),             write_descendant_chain(P, A)    ).%write_child(Child, Parent).write_child(C, P) :-     child(C, P),     write(C),     write(' is a child of '),     write(P),     nl.
Harry Potter's Family Tree Database
beginner;homework;database;prolog