sibling(X,Y) :- parent(Z,X), parent(Z,Y).
parent(X,Y) :- father(X,Y).
parent(X,Y) :- mother(X,Y).
mother(trude, sally).
father(tom, sally).
father(tom, erica).
father(mike, tom).
female(trude).
male(tom).
male(mike).
% Checks so that the user doesn't try and do things he or she shouldn't
check(sibling(_,_)).
check(parent(_,_)).
check(mother(_,_)).
check(father(_,_)).
check(male(_)).
check(female(_)).
check((X,Y)) :- check(X), check(Y).
check((X;Y)) :- check(X), check(Y).
check('!').
go(Get) :-
% Get the query from the GET request
member(q=Query,Get),
% Convert to a term
catch(atom_to_term(Query, Term, Bindings),_,fail),
nonvar(Term),
% Check user has supplied a valid query
check(Term),
!,
% Find all solutions
forall(Term, (bind(Bindings), write(Term), nl)),
!.
% This binds a Variable=Name list so that unbound variables are bound to their Name
bind([]).
bind([A=A|T]) :-
!,
bind(T).
bind([_|T]) :-
bind(T).
/*<html>
<head>
<title>PSP Demo</title>
</head>
<body>
<a href="template.prolog?t=psp#psp">Back</a><br>
<a href="family.html">View Source</a><br><br>
<!-- Just show the database, plain old text -->
Database:
<pre>
sibling(X,Y) :- parent(Z,X), parent(Z,Y).
father(X,Y) :- parent(X,Y), male(X).
mother(X,Y) :- parent(X,Y), female(X).
parent(X,Y) :- father(X,Y).
parent(X,Y) :- mother(X,Y).
mother(trude, sally).
father(tom, sally).
father(tom, erica).
father(mike, tom).
female(trude).
male(tom).
male(mike).
</pre>
<!-- Work out what the query was -->
<?, (member(q=Query,Get);Query='No Query Supplied') ,?>
<!-- Show the query -->
Query:
<pre>
<?= Query ?>
</pre>
<!-- Show the solutions -->
Solutions:
<pre>
<?, once(
go(Get)
;
?>Error: Invalid Term (The query must be a valid prolog query)<?
)
,?></pre>
<!-- And have an input box for the next query -->
<form method="GET" action="family.prolog">
New Query: <input type="text" name="q"><br>
<input type="submit">
</form>
Sample Queries:
<pre>
male(X).
sibling(X,Y).
father(X,sally).
sibling(sally,X).
parent(X,Y),parent(Y,Z).
</pre>
</body>
</html>*/