Опубликован: 12.02.2014 | Уровень: для всех | Доступ: платный
Лекция 12:
Язык запросов
12.2. Определение основных отношений
В настоящем параграфе определяются основные родственные отношения.
Создается класс relation для описания родственных отношений. Аргументами всех отношений являются идентификаторы людей. Ниже приведен интерфейс relation (файл relation.i).
properties
db : dbrel.
predicates
parent: (unsigned, unsigned) nondeterm (o,i) (o,o) (i,o) (i,i).
father: (unsigned, unsigned) nondeterm (o,i) (o,o) (i,o) (i,i).
mother: (unsigned, unsigned) nondeterm (o,i) (o,o) (i,o) (i,i).
husband: (unsigned, unsigned) nondeterm (o,i) (i,o) (o,o).
son: (unsigned, unsigned) nondeterm (o,i) (o,o).
daughter: (unsigned, unsigned) nondeterm (o,i) (o,o).
sister: (unsigned, unsigned) nondeterm (o,i) (o,o).
brother: (unsigned, unsigned) nondeterm (o,i) (o,o).
ancestor: (unsigned, unsigned) nondeterm (o,i) (i,o) (o,o) (i,i).
Пример
12.5.
Интерфейс relation
Объявление конструктора приведено в листинге 12.6 (файл relation.cl).
constructors
new: (dbrel).
Пример
12.6.
Декларация класса relation
Ниже приведена имплементация (файл relation.pro).
facts
db: dbrel.
clauses
new(Db):-
db := Db.
predicates
male: (unsigned [out]) nondeterm.
female: (unsigned [out]) nondeterm.
clauses
male(Id):-
db:person_nd(Id, _, _, dbrel::male, _, _).
female(Id):-
db:person_nd(Id, _, _, dbrel::female, _, _).
clauses
father(IdF, IdCh):-
db:person_nd(IdCh, _, _, _, IdF, _),
IdF > 0.
mother(IdM, IdCh):-
db:person_nd(IdCh, _, _, _, _, IdM),
IdM > 0.
parent(IdP, IdCh):-
father(IdP, IdCh);
mother(IdP, IdCh).
husband(IdH, IdW):-
db:spouse_nd(IdH, IdW).
son(IdS, IdP):-
male(IdS),
parent(IdP, IdS).
daughter(IdD, IdP):-
female(IdD),
parent(IdP, IdD).
ancestor(IdA, IdD):-
parent(IdA, IdD).
ancestor(IdA, IdD):-
parent(IdA, X),
ancestor(X, IdD).
predicates
sister_nd: (unsigned, unsigned) nondeterm (o,i) (o,o).
brother_nd: (unsigned, unsigned) nondeterm (o,i) (o,o).
get_nd: (A*) -> A nondeterm.
clauses
sister_nd(IdS, IdSib):-
female(IdS),
parent(P, IdS),
parent(P, IdSib),
IdS <> IdSib.
brother_nd(IdB, IdSib):-
male(IdB),
parent(P, IdB),
parent(P, IdSib),
IdB <> IdSib.
brother(IdB, Id):-
free(Id),
tuple(IdB, Id) = get_nd([tuple(I, I1) || brother_nd(I, I1)]).
brother(IdB, Id):-
bound(Id),
IdB = get_nd([I || brother_nd(I, Id)]).
sister(IdS, Id):-
free(Id),
tuple(IdS, Id) = get_nd([tuple(I, I1) || sister_nd(I, I1)]).
sister(IdS, Id):-
bound(Id),
IdS = get_nd([I || sister_nd(I, Id)]).
get_nd(L) = list::getMember_nd(list::removeDuplicates(L)).
Пример
12.7.
Имплементация класса relation
Предикат free/1 истинен, если его аргумент является свободной переменной, а предикат bound/1, соответственно, если конкретизированной.