1
votes

So I have this knowledge base

family(person(name(tom),surname(fox),date(7,may,1950),job(bbc,15200)),
       person(name(ann),surname(fox),date(9,may,1951),job(unemployed)),
       children[person(name(pat),surname(fox),date(5,may,1973),job(unemployed)),
                person(name(jim),surname(fox),date(5,may,1973),job(unemployed))]).

family(person(name(john),surname(doe),date(7,july,1957),job(carpenter,12300)),
       person(name(lucy),surname(doe),date(19,february,1969),job(clerk,13500)),
       children[person(name(mary),surname(doe),date(17,january,1990),job(unemployed)),
                person(name(mat),surname(doe),date(4,may,1991),job(unemployed)),
                person(name(george),surname(doe),date(5,august,1993),job(unemployed))]).

family(person(name(nick),surname(brown),date(14,may,1955),job(trucker,16300)),
       person(name(carmen),surname(brown),date(25,april,1957),job(unemployed)),
       children[person(name(david),surname(brown),date(15,august,1977),job(unemployed)),
                person(name(james),surname(brown),date(7,october,1980),job(unemployed))]).

family(person(name(daniel),surname(sturgess),date(19,november,1956),job(unemployed)),
       person(name(susan),surname(sturgess),date(18,october,1957),job(manager,15400)),
       children[person(name(mick),surname(sturgess),date(5,december,1982),job(unemployed))]).

And what I'm trying to do is figure out a way to create a predicate wife/1 that will return all the working wives, and a predicate exists/1 that will return all the unemployed parents that are born before 1963.

I'm quite new to Prolog (using the swi environment) so any help is welcome!

1
@CapelliC for some reason I'm getting a Syntax error: Operator expected at lines 3:11, 8:11, 14:11 and 19:11, but that's between the "i" and the "l" of each children list.. what gives?Xenofonos
you're missing the open parenthesis surrounding the lists, that is, should be children([person(...),person(...)]). I also have a bug in my answer: job(Title,Salary) will not match: see my edit...CapelliC
Thank you for your quick and precise answer once again CapelliC!Xenofonos

1 Answers

0
votes

Your database is in unusual format, since in Prolog attributes are normally associated to positions. Since you name all attributes, some flexibility is allowed. Assuming a 'working wife' it's the second entry of family/2 having a job \= unemployed at fixed (last) position:

wife(W) :- family(_,W,_), W = person(_,_,_,job(Job)), Job \= unemployed.

to get all:

?- findall(W, wife(W), Wives).

if job/1 attribute can appear in some other argument position, we can generalize the above clause:

wife(W) :- family(_,W,_), W =.. [person|Attrs], memberchk(job(Job), Attrs), Job \= unemployed.

exists/1 can be handled in similar way...

edit

correction to match job attribute: it appears with 1 or 2 arguments: assuming when a person is employed, s(he) will always have a salary, we can simplify matching job/2:

wife(W) :- family(_,W,_), W = person(_,_,_,job(_,_)).