に触発された
「Prolog での RDBMS 操作」を試してみたかった (実際、これは多かれ少なかれ Datalog です)
問題文
「映画に出演している俳優」のデータベースが与えられた場合:
starsin(a,bob).
starsin(c,bob).
starsin(a,maria).
starsin(b,maria).
starsin(c,maria).
starsin(a,george).
starsin(b,george).
starsin(c,george).
starsin(d,george).
与えられた映画のセットから、そのセットのすべての映画に出演した俳優を見つけます。
私は最初は醜い解決策を持っていましたが、その後...
素敵な解決策
問題を明確にします。
セットは重複のないリストで表され、場合によっては順序付けられます。
- 映画のセットが与えられた場合
MovIn
- ...アクターのセットを見つける
ActOut
- ... ... そのような: のすべての俳優
ActOut
が (少なくとも) すべての映画に出演MovIn
- ... ... 再定式化: のアクターの映画のセット は のスーパーセットです。
MovAx
Ax
ActOut
MovIn
setof/3は正しいトップレベル述語のようです。ポイント 1 と 2のAnsatzは次のとおりです。
setof(Ax, (... MovIn ...) , ActOut).
に登場する映画MovAx
のセットである場合Ax
、使用できます
- ライブラリ(リスト)の サブセット/2または
- ord_subset/2 of library(ordset) ... すべてが ordset であることを確認できる場合。
を使いましょうsubset/2
。
ポイント4は、私たちに次のように書かせるようです:
setof(Ax, (..., subset(MovAx, MovIn)) , ActOut).
...
...を開発する
setof(Ax, ( setof(Mx,starsin(Mx,Ax),MovAx) , subset(MovIn, MovAx) ) , ActOut).
これはもうありそうです!
λ 式はあるのに、キーボードや構文に λ がないときの感触。
終わり!
述語にまとめる:
actors_appearing_in_movies(MovIn,ActOut) :-
setof(Ax, ( setof(Mx,starsin(Mx,Ax),MovAx) , subset(MovIn, MovAx) ) , ActOut).
残念ながら、上記は機能しません。
どうやらすべてを別の にラップする必要があるようですsetof/3
が、なぜですか??
?- actors_appearing_in_movies([a,b],ActOut).
ActOut = [maria] ;
ActOut = [george].
完了、2 つ取ります
以下は機能します:
subselect(Ax,MovIn) :-
setof(Mx,starsin(Mx,Ax),MovAx), subset(MovIn, MovAx).
actors_appearing_in_movies(MovIn,ActOut) :-
setof(Ax, subselect(Ax,MovIn) , ActOut).
?- actors_appearing_in_movies([a,b],ActOut).
ActOut = [george, maria].
テスト
テストは、いくつかの目標を実行しているだけです。
映画の空のセットについては、すべての俳優を取得することに注意してください。これは間違いなく正しいです。すべての俳優が空のセットのすべての映画に出演します。
actors_appearing_in_movies([],ActOut),permutation([bob, george, maria],ActOut),!.
actors_appearing_in_movies([a],ActOut),permutation([bob, george, maria],ActOut),!.
actors_appearing_in_movies([a,b],ActOut),permutation([george, maria],ActOut),!.
actors_appearing_in_movies([a,b,c],ActOut),permutation([george, maria],ActOut),!.
actors_appearing_in_movies([a,b,c,d],ActOut),permutation([george],ActOut),!.
質問
私は何を逃しましたか
actors_appearing_in_movies(MovIn,ActOut) :-
setof(Ax, ( setof(Mx,starsin(Mx,Ax),MovAx) , subset(MovIn, MovAx) ) , ActOut).