在Prolog中检查列表

时间:2012-12-26 17:46:50

标签: prolog

我正在尝试制定一个在Prolog中有约束的时间表。调度将基于两个约束。同一学期的课程和同一教师讲授的课程不能安排在同一时段。

course(ceng123,1). 课程代码和学期当然。

slot(monday,1). 白天和小时。

teaches(jack,ceng123). 老师和课程代码。

 course(cse111,1).
 course(cse112,1).
 course(cse113,1).
 course(cse114,1).
 course(cse115,2).
 course(cse116,2).
 course(cse117,2).
 course(cse118,2).
 slot(monday,1).
 slot(monday,2).
 slot(tuesday,1).
 slot(tuesday,2).
 teaches(erkan,cse111).
 teaches(erkan,cse112).
 teaches(erkan,cse113).
 teaches(erkan,cse114).
 teaches(merkan,cse115).
 teaches(merkan,cse116).
 teaches(kan,cse117).
 teaches(kan,cse118).

我期待的答案是:

 ?- schedule([cse111,cse112,cse113,cse114,cse115,cse116,cse117,cse118],X).
 X = [cse111, monday, 1, cse112, monday, 2, cse113, tuesday, 1, cse114, tuesday, 2, cse115, monday, 1, cse116, monday, 2, cse117, tuesday, 1, cse118, tuesday, 2]

我编写了一个没有约束的代码:

 course(cse111,1).
 course(cse112,1).
 course(cse113,1).
 course(cse114,1).
 course(cse115,2).
 course(cse116,2).
 course(cse117,2).
 course(cse118,2).
 slot(monday,1).
 slot(monday,2).
 slot(tuesday,1).
 slot(tuesday,2).
 teaches(erkan,cse111).
 teaches(erkan,cse112).
 teaches(erkan,cse113).
 teaches(erkan,cse114).
 teaches(merkan,cse115).
 teaches(merkan,cse116).
 teaches(kan,cse117).
 teaches(kan,cse118).


 schedule([],[]).
 schedule([Course|CourseTail],[Course,Day,Slot|ScheduleTail]):-
     slot(Day,Slot),schedule(CourseTail,ScheduleTail).

没有问题,但是当我尝试这个时;

 course(cse111,1).
 course(cse112,1).
 course(cse113,1).
 course(cse114,1).
 course(cse115,2).
 course(cse116,2).
 course(cse117,2).
 course(cse118,2).
 slot(monday,1).
 slot(monday,2).
 slot(tuesday,1).
 slot(tuesday,2).
 teaches(erkan,cse111).
 teaches(erkan,cse112).
 teaches(erkan,cse113).
 teaches(erkan,cse114).
 teaches(merkan,cse115).
 teaches(merkan,cse116).
 teaches(kan,cse117).
 teaches(kan,cse118).     

 schedule([],[]).
 schedule([Course|CourseTail],[Course,Day,Slot|ScheduleTail]):-
     schedule(CourseTail,ScheduleTail), check(Course,Day,Slot,ScheduleTail).

 check(_, _, _,[]).
 check(Course,Day,Slot,[Course2,Day2,Slot2|Tail]):- check(Course,Day,Slot,Tail),
     course(Course,Semester1),course(Course2,Semester2),Semester1=\=Semester2, 
     slot(Day,Slot),slot(Day2,Slot2).

我试着写约束但我犯了一个错误。

 uncaught exception: error(syntax_error('user_input:1 (char:4) . or operator expected           after expression'),read_term/3) 

你能看到错误吗?

2 个答案:

答案 0 :(得分:3)

Singleton变量是一个变量,在程序中只提到一次:See wiki。你得到第27行我认为是这一行:check(Course,Day,Slot,[])。您可以将其替换为check(_, _, _,[])。 ('_'表示任何变量。这意味着您可以普遍量化变量。)

您没有收到错误消息。 Prolog说不,只是意味着你的约束无法满足。

答案 1 :(得分:0)

首先应明确定义约束。 从您的评论中,我读到: 一小时内的两门课程不能有相同的学期编号,同一教师的课程也不会在同一时间内完成。

因此,您可以在满足这些要求时为课程分配计划,暗示您必须知道已经发布了哪些作业。因此,您可以创建一个保留当前计划的过程,并仅在满足要求时添加新的作业。

首先,定义调用带有空列表的新过程schedule/2的{​​{1}}过程:

schedule/3

现在,此过程在第一个参数上有分配计划的课程列表,将当前作业保留为第二个参数,并将第三个参数与最终计划统一(使用您需要的数据,即课程,日和插槽)。 我将使用一个结构来表示每个作业schedule(Courses,Schedule):- schedule(Courses, [], Schedule). ,因为只是将这些数据混合在列表中并不是一个好主意。

schedule(Course, Day, Slot)

第一个条款是基本情况。它指出,当输入列表中没有其他课程时,时间表将为空。

第二个子句从输入列表中获取第一个课程,并为该课程计算可能的学期,教师和日/插槽,然后检查是否满足约束条件。它测试是否已有该日/时段/学期的时间表以及该日/时段是否已有教师作业。如果满足要求,那么我们将此分配添加到当前分配列表并继续递归。

返回后,我们将课程/日/插槽添加到最终的时间表列表中。