【问题标题】:accessing relations within prolog在 prolog 中访问关系
【发布时间】:2020-09-17 11:59:01
【问题描述】:

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

创建一个模拟学生、班级、房间、日期和 他们的关系。包含相关函数

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

显然,似乎有两种策略,使用图(似乎很复杂)或使用此映射策略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                               
}

但我真的不知道该怎么做。总结一下我的问题。

我当前的方法是否应该起作用,我如何才能基于另一个关系(彼得 苏珊)检索一个关系的值? 如果我目前的方法不起作用,您建议如何处理这项任务

【问题讨论】:

  • 当您编写semester_subjects(2, DM). 时,您是在说DM 是一个变量。如果你想让它成为一个原子,你必须写semester_subjects(2, dm).

标签: prolog relation relational


【解决方案1】:

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

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

你有“对象”

  • 学生具有属性姓名班级学期

这由 Prolog 中的 谓词 student/3 建模。在relational database terminology / the relational model 中,这称为关系

看起来不同(想象一下它是表格形式),但是......同样的东西。

你有“省略的对象”

  • semester 属性为 semester id,值为 1 或 2
  • subject 具有属性 subject name,具有值 DMtest 等。

没有使用谓词明确列出(尽管这是可能的,并且建议取决于应用程序),如下所示:

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

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

  • semester 通过 semester_subjectssubject 相关

这是通过谓词(又名关系)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').

完成后,您可以提出查询

例如:

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).

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

【讨论】:

    猜你喜欢
    • 2019-11-29
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多