0

I have the following facts

%exam(Student,Subject)

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

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

exam(student1,subject3).

I want to find the subjects of a student and put them in a list

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

I can't figure out what the base case should be !

4

1 回答 1

1

\+ Subject = H意思是“不能证明Subject可以与 统一H

但是由于H开始时没有实例化,它总是可以与 统一Subject,所以这个目标总是会失败。

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

只要你能找到一个新的事实,你就将它添加到这个累积列表中,然后继续;但如果你找不到新的事实,你应该停下来。这将是你的基本情况。使用辅助谓词进行编码会更容易,每个谓词都执行其单独的任务(例如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

于 2013-03-28T10:43:46.407 回答