Опубликован: 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, соответственно, если конкретизированной.