0

私は次の事実を持っています

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

ベースケースがどうあるべきかわかりません!

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

このセットアップの欠点は、2 次になることです。assertのような論理外の機能や、ビルトインなどを使用しないと、線形にすることはできませんfindall

于 2013-03-28T10:43:46.407 に答える