4

質問をする別の方法は次のとおりです。

原子のすべてのプロパティを一覧表示するにはどうすればよいですか?

例えば:

movie(agora).
director(agora, 'Alejandro Amenabar')
duration(agora, '2h').

agoraそのため、引数の述語をすべて受け取りたいと思います。この場合moviedirectorduration、 、その他のパラメータ('Alejandro Amenabar', '2h').

私は見つけました: this、およびthis question ですが、よく理解できませんでした。

PersonInvited映画について何か気に入らない場合は、「変数回答」に false の値を設定したいと思います。

私のクエリは次のようになります。

answer(Answer, PersonInvited, PersonWhoMadeInvitation, Movie)

答え:この監督は好きじゃない

answer(false, PersonInvited, PersonWhoMadeInvitation, Movie):-
    director(Movie, DirectorName),not(like(PersonInvited,DirectorName)).

たとえば、ジャンルなどのプロパティでも同じことが起こります。

答え: このジャンルは好きじゃない

answer(false, PersonInvited, PersonWhoMadeInvitation, Movie):-
    genre(Movie, Genre), not(like(PersonInvited,Genre)).

したがって、すべてのオブジェクトのすべての機能を繰り返し記述するのではなく、この状況を一般化したいと思います。

4

6 に答える 6

3

I found two solutions the 2nd is cleaner from my point of view, but they are different.

Parameters:

  • PredName: Name of the predicate.
  • Arity: The Arity of the Predicate.
  • ParamValue: If I want to filter by one specific parameter.
  • PosParam: Which is the position of the parameter in the predicate.
  • ListParam: All the value of the posibles values parameters (mustbe a Variable all the time).

Solution 1:

filter_predicate(PredName, Arity, ParamValue,PosParam, ListParam):-
    current_predicate(PredName/Arity),
    Arity >= PosParam,
    nth(PosParam, ListParam, ParamValue),
    append([PredName], ListParam, PredList),
    GlobalArity is Arity + 1,
    length(PredList, GlobalArity),
    Predicate =.. PredList,
    Predicate.

Query

filter_predicate(PredName, Arity, agora, 1, Pm).

Output

Arity = 2                                                                              
Pm = [agora,'Alejandro Amenabar']
PredName = director ? 

yes

Solution2:

filter_predicate(PredName, Arity, ParamList):-
    current_predicate(PredName/Arity),
    append([PredName], ParamList, PredList), 
    GlobalArity is Arity + 1,
    length(PredList, GlobalArity),
    Predicate =.. PredList,
    Predicate.

Query 1:

filter_predicate(PredName, Arity, [agora, X]).

Output

Arity = 2
PredName = director
X = 'Alejandro Amenabar' ? 

Query 2:

filter_predicate(PredName, Arity, [X, 'Alejandro Amenabar']).

Output

Arity = 2
PredName = director
X = agora ? 
于 2015-10-02T10:28:05.120 に答える
2

ここにSWI-Prologを使用した私の試みがあります

?- current_predicate(so:F/N), N>0, length(As,N), Head =.. [F|As], clause(so:Head,Body), As=[A|_], A==agora.

so the factsと呼ばれるモジュールにコーディングしたことに注意してください。そのため、関連する呼び出しをモジュール名で修飾します。このようなビルトイン (/2 およびcurrent_predicate /1) は ISO に準拠していますが、モジュール (SWI-prolog 内) は準拠していません。なので携帯性等は不明です…

節/2 メタ解釈を簡単に書くためのビルトインです。このプロローグの歴史的な「強み」のすばらしい紹介については、リンクを参照してください。

最後の 2 回の呼び出し (As=[A|_], A==agoraつまり ) は、最初の引数として変数を持つ句の一致を回避します。

于 2015-09-30T12:25:58.677 に答える
0

GNU Prolog をバックエンド コンパイラとして Logtalk を使用するソリューションのドラフト:

% a movie protocol
:- protocol(movie).

    :- public([
        director/1,
        duration/1,
        genre/1
    ]).

:- end_protocol.


% a real movie
:- object('Agora',
    implements(movie)).

    director('Alejandro Amenabar').
    duration(120).
    genre(drama).

:- end_object.


% another real movie
:- object('The Terminator',
    implements(movie)).

    director('James Cameron').
    duration(112).
    genre(syfy).

:- end_object.


% a prototype person
:- object(person).

    :- public([
        likes_director/1,
        likes_genre/1
    ]).

    :- public(likes/1).
    likes(Movie) :-
        conforms_to_protocol(Movie, movie),
        (   Movie::genre(Genre),
            ::likes_genre(Genre) ->
            true
        ;   Movie::director(Director),
            ::likes_director(Director) ->
            true
        ;   fail
        ).

:- end_object.


% a real person
:- object(mauricio,
    extends(person)).

    likes_director('Ridlye Scott').

    likes_genre(drama).
    likes_genre(syfy).

:- end_object.

いくつかのサンプル クエリ:

$ gplgt
...

| ?- {movies}.
...

(5 ms) yes
| ?- mauricio::likes('Agora').

true ? 

yes
| ?- mauricio::likes(Movie).  

Movie = 'Agora' ? ;

Movie = 'The Terminator' ? ;

no

| ?- 'The Terminator'::director(Director).

Director = 'James Cameron'

yes

コードはいくつかの方法で改善できますが、このソリューションを評価するための明確なアイデアを得るには十分です。

于 2015-10-01T14:56:56.010 に答える
0

プロローグで行をリストに読み込む

すべての述語はファイル「my_file.pl」にあります。

たとえば、my_file.pl には以下が含まれます。

movie(agora).
director(agora, 'Alejandro Amenabar').
duration(agora, '2h').

以下を使用できます。

getLines(File,L):-
 setup_call_cleanup(
 open(File, read, In),
 readData(In, L),
 close(In)
 ).

readData(In, L):-
  read_term(In, H, []),
  (   H == end_of_file
  ->  L = []
  ;   L = [H|T],
      readData(In,T)
  ).


pred_arg_file(Pred,Argue,File):-
  getLines(File,L),
  member(M,L),
  M=..List,
  member(Argue,List),
  List=[Pred|_].

次に、クエリを実行できます。

 ?-pred_arg_file(Pred,agora,'my_file.pl').
 Pred = movie ;
 Pred = director ;
 Pred = duration ;
 false

また

?- findall(Pred,pred_arg_file(Pred,agora,'my_file.pl'),Preds).
Preds = [movie,director,duration].

プロパティを返したい場合は、head だけでなく List 全体を返します。

pred_arg_file(List,Argue,File):-
  getLines(File,L),
  member(M,L),
  M=..List,
  member(Argue,List).
于 2015-09-30T11:59:52.610 に答える
0

私の理解では、関係を照会できるようにデータ表現を変更する必要があります。他の回答が指摘しているように、トリプルを使用すると、すべての関係をこの形式に変更するコードを簡単に記述できます。次に、好きなものや嫌いなものを保存する最善の方法を見つける必要があります。これは、否定の動作に影響します。この例では:

relation(starwars,is,movie).
relation(lucas, directs,starwars).
relation(agora, is,movie).
relation('Alejandro Amenabar', directs, agora).
relation(agora, duration, '2h').

like(ma,'Alejandro Amenabar').
like(ma,movie).
like(ma,'2h').

ma_does_not_want_to_go(Film):-
  relation(Film,is,movie),
  relation(Film,_,Test), \+like(ma,Test).
ma_does_not_want_to_go(Film):-
  relation(Film,is,movie),
  relation(Test,_,Film), \+like(ma,Test).

ma_wants_to_go(Film):-
  relation(Film,is,movie),
  \+ma_does_not_want_to_go(Film).

sa_invites_ma(Film,true):-
  ma_wants_to_go(Film).

sa_invites_ma(Film,false):-
  ma_does_not_want_to_go(Film).
于 2015-10-01T12:09:32.790 に答える