如何在prolog事实中递归搜索

时间:2013-03-28 10:05:21

标签: search prolog counter

我有以下事实

%exam(Student,Subject)

exam(student1,subject1).
exam(student2,subject1).
exam(student3,subject1).

exam(student1,subject2).
exam(student3,subject2).

exam(student1,subject3).

我想找到学生的科目并将其列入名单

Subjects(Student,[H|T]):-
                        exam(Student,Subject),
                        \\+Subject=H,
                        H = Subject,
                        Subjects(Student,T).

我无法弄清楚基本情况应该是什么!

1 个答案:

答案 0 :(得分:1)

\+ Subject = H表示“无法证明Subject可以与H统一。

但是,由于H开始未经实例化,因此可以始终与Subject统一,因此目标始终会失败。

此外,要查看之前是否找到Subject,您必须在之前找到的值的列表中检查其成员资格。这意味着,在call to call中携带一个额外的参数,该参数将从[]开始,将新发现的主题添加到其中,并使用更新的列表进行下一次调用。

只要您能找到新的事实,就可以将其添加到此累积列表中,然后继续;但如果你找不到新的事实,你应该停下来。这将是你的基本情况。使用辅助谓词进行编码会更容易,每个辅助谓词都执行单独的任务(如can_find_new_subject( Student, ListSeenSoFar, Subject)等)。

subjects(Student, L):- search_subjects(Student, [], L).

search_subjects(Student, Seen, L):-
  find_new_subject(Student, Seen, Subj)
  search_subjects(Student, [Subj|Seen], L).

search_subjects(Student, Seen, L):-
  \+ find_new_subject(Student, Seen, Subj),
  ... .

find_new_subject( ......
  .... 

这种设置的缺点是它将是二次的。如果没有像assert这样的额外逻辑工具,或者使用内置的findall等,您就无法使其成为线性。