在序言中访问关系

accessing relations within prolog

在我的离散数学课程中,我们有一个序言作业如下

Create a program that models students, classes, rooms, dates, and their relations. Include relevant functions

我最初的想法是需要生成大量数据,我仍然很好奇是否可以在不显式映射每个关系的情况下完成此任务。

显然似乎有两种策略,使用图(看起来很复杂)或使用此映射策略 relation(value, value2)(我想称它为谓词,但我不确定那是否是对)。

但是我似乎无法弄清楚如何访问规则内的关系? (我的意思是 :- 语法,对我来说更像是函数而不是规则)

我觉得我在偏离轨道,我在查找解决此问题所需的信息时遇到问题,因为我对术语有困难。

%student(name, class, semester)
student(søren, 101, 1).
student(jens, 101, 1).
student(peter, 101, 2).
student(eskild, 101, 1).
student(jørgen, 101, 2).
student(signe, 101, 1).
student(pernille, 101, 2).
student(katrine, 101, 2).
student(sophie, 101, 1).
student(liva, 101, 1).
%semester_subjects(semester, subject)
semester_subjects(2, DM).
semester_subjects(1, test).
semester_subjects(2, BI).
semester_subjects(1, SI).
semester_subjects(1, LSD).
semester_subjects(2, SI).
semester_subjects(2, LSD).
%class(name, subject)
class(101, DM).
class(101, test).
class(101, SI).
class(101, LSD).
class(101, BI).
%schedule(weekday(0-6), subject)
schedule(0, test).
schedule(1, test).
schedule(1, BI).
schedule(2, SI).
schedule(2, LSD).
schedule(4, DM).

%has_class_today(student_name, day) :-.
%has_sudent(class, student_name) :-.
%has_subject(student_name, subject_name) :-.

我觉得我应该可以做一些像

has_class_today(student_name, day) :- {
    Class = student(søren).class
    Semester = student(søren).semester
    SemesterSubjects = semester_subjects.forAll( if(semester == Semester) return subject)
    SubjectsToday = schedule(day).forAll(if(SemesterSubjects.includes(subject))
    if(SubjectsToday > 0) return true
    else return false                               
}

但我实在想不出该怎么做。总结一下我的问题。

我当前的方法是否应该起作用,我如何才能基于另一个关系检索一个关系 (Peter <-> Susan) 的值? 如果我目前的方法不起作用,你会建议如何解决这个任务

这很难解释,需要至少 2 小时的指导。

这是一个标准的数据库建模作业。

您有“对象”

  • 学生,属性为姓名class学期

它由 Prolog 中的 predicate student/3 建模。在 relational database terminology / the relational model 中,这称为 关系 table.

看起来不同(假设它是表格形式),但是...相同。

您有“被忽略的对象”

  • 学期,属性为 学期 ID,值为 1 或 2
  • subject with attribute subject name, with with values DM, test etc..

没有使用谓词明确列出(尽管这是可能的,并且根据应用程序推荐)如:

semester(1).
semester(2).
subject("DM").
subject("test").

相反,这些对象通过给出它们之间的 2 位关系隐式列出

  • 学期主题相关,通过semester_subjects

这是通过谓词(又称关系)建模的 semester_subjects/2

等等

(请注意,您的代码有误。Prolog 会将任何以大写字母开头的内容视为变量,因此您必须键入 "DM"'DM' 而不是 DM。 )

转到 SWISH 并输入您的数据。

% The student relation: student(name, class, semester)
% A predicate made up by a set of facts.

student('søren', 101, 1).
student('jens', 101, 1).
student('peter', 101, 2).
student('eskild', 101, 1).
student('jørgen', 101, 2).
student('signe', 101, 1).
student('pernille', 101, 2).
student('katrine', 101, 2).
student('sophie', 101, 1).
student('liva', 101, 1).

% The relation expressing the connection/relationship  
% between semester and subjects
% semester_subjects(semester, subject)
% A predicate made up by a set of facts.

semester_subjects(2, 'DM').
semester_subjects(1, 'test').
semester_subjects(2, 'BI').
semester_subjects(1, 'SI').
semester_subjects(1, 'LSD').
semester_subjects(2, 'SI').
semester_subjects(2, 'LSD').

% The relation expressing the connection/relationship  
% between class and subject
% class(name, subject)
% A predicate made up by a set of facts.

class(101, 'DM').
class(101, 'test').
class(101, 'SI').
class(101, 'LSD').
class(101, 'BI').

% The relation expressing the connection/relationship  
% between weekday and subject
% schedule(weekday(0-6), subject)
% A predicate made up by a set of facts.

schedule(0, 'test').
schedule(1, 'test').
schedule(1, 'BI').
schedule(2, 'SI').
schedule(2, 'LSD').
schedule(4, 'DM').

完成后,您可以询问 queries:

例如:

student(SNAME,CLASS_ID,SEMESTER),class(CLASS_ID,CLASS_NAME).

这意味着:

检索所有元组“SNAME,CLASS_ID,SEMESTER,CLASS_NAME”,您可以在其中并置 student 关系的一个元素(或者 student 谓词)和 class 关系的一个元素(或者,class 谓词的一个事实)使得值 CLASS_ID 以相同的方式出现在两者中。这分明是database JOIN operation.

然后您可以通过使用单个子句定义新谓词来重新打包该查询,其中出现您感兴趣的值:

interesting(SNAME,CLASS_NAME) :- student(SNAME,CLASS_ID,SEMESTER),class(CLASS_ID,CLASS_NAME).

并将其添加到程序中。

完成后,您可以发出新的表单查询

interesting(S,C).

最后,你需要自己尝试一下。这是唯一的方法。