1

PHP を Prolog に正常に接続し、ファイルに存在する必要なナレッジ ベースをクエリし、関数knowledge_base.plを介して結果をエコーすることができました。php exec

true各クエリの実行後に Prolog が返す/false値をエコーする際に問題が発生したため (前の質問を参照)、実装に問題がある解決策を思いつきました。

knowledge_base.plこれらの事実とルールを含む単純なファイルがあるとします。

girl(erin).
boy(john).

likes(erin, reading).
likes(john, reading).

hangs_out_with(erin, X) :-
    likes(X, reading),
    boy(X),
    writeln('Someone s got a new friend!!').

が女の子かどうかを知りたいとしましょう。erinもしそうなら、それが本当だと書くか、そうでなければ、それが間違っていると書きましょう。knowledge_base.plこれをファイルに追加しました:

girl(erin) :-
        girl(erin)
     -> write('it is true')
     ;  write('it is not true'). 

クエリを入力すると?- girl(erin).out of local stackエラーが発生します。Web を検索したところ、これは無限再帰によるものであることがわかりました。

だれか書き方のヒントをくれませんか

girl(X) :-
    (    girl(X)
      -> write('it is true')
      ;  write('it is not true')).  

プロローグで?前もって感謝します。

新しいユーザーとして、私は写真を投稿することを許可されていません。

SWI-Prolog の出力:

1 ?-hangs_out_with(erin,kosta).
false.

2 ?-hangs_out_with(erin,john).
Someone s got a new friend!!
true.

コマンド プロンプトの出力:

C:\(directory)>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,kosta),halt.
1 ?-halt. (the halt is inputted by me.)
C:\(directory)>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,john),halt.
Someone s got a new friend!!

最初のクエリは失敗し、2 番目のクエリは成功します。ご覧のとおり、クエリ実行後のプロローグは true/false を出力しますが、コマンド プロンプトで同じクエリを実行すると、true/false 値はエコーされません!!

4

3 に答える 3

2

聞いてみるといいと思います

is_girl(X) :-
    girl(X) -> write('t is true') ; write('it is not true'). 

編集

こういうことですか?

is_type(Type, X) :-
    call(Type, X) -> writeln(yes); writeln(no).
于 2012-09-16T08:04:34.630 に答える
1

そのため、コマンド シェルで Prolog クエリを実行し、その出力をキャプチャして分析することにより、「PHP を Prolog に接続」します。http://www.swi-prolog.org/man/quickstart.html言う

「2.1.1.1 Unix での SWI-Prolog の起動

デフォルトでは、SWI-Prolog は「swipl」としてインストールされます。SWI-Prolog 自体とそのユーティリティ プログラムのコマンドライン引数は、標準の Unix マニュアル ページを使用して文書化されています。」

そのため、「-q」スイッチに関するマニュアル ページを参照してください。おそらく静かな「-q」ですか?「-f」とはどういう意味ですか (わかりました、それはおそらく「ファイル」です)? しかし、解決策は同じです。新しい述語に別の名前を使用するだけです。

最初の試行では、

C:>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,kosta),halt.
1 ?-halt. (the halt is inputted by me.)

halt失敗したため、実行されませhangs_out_with(erin,kosta)ん。コンマは接続詞 ("and") を表します。

必要なことは、目標が真か偽かを報告する新しい述語を作成することだけで、常に成功します。

report_hangs_out_with(A,B):-
  hangs_out_with(A,B)- > writeln(['YES',A,B]) ; writeln('NO').

代わりにそれを使用してください:

C:>swipl -q -f knowledge_database.pl -g report_hangs_out_with(erin,kosta),halt.

また、「true」または「false」をエコーする Prolog は、対話型セッションの一部です。ただし、halt!で終了します。


編集:あなたが投稿した:

1 ?-hangs_out_with(erin,kosta).
false.

そのため、インタラクティブな Prolog シェルでそのクエリを実行すると、失敗が報告されます。halt/0Prolog シェルを終了します。コマンド ライン スイッチでゴールを指定して実行すると、成功または失敗が報告されないようです。これは、私たちユーザー (およびコンパイラー作成者) に関する限り、自然の事実です。私があなたに示したもので簡単に対処できます。そして、あなた自身もそれがうまくいくと言っています。失敗または成功する述語ごとに、先ほど示したように、別のレポート述語を定義します。

サンプルのトランスクリプトを次に示します (Windows の場合ですが、関係ありません)。それはあなたの疑問を解決するはずです:

C:\Program Files\pl\bin>plcon -q -g (writeln('****'),halt).
****                          // didn't say Yes, right??

C:\Program Files\pl\bin>plcon -q
1 ?- writeln('****'),halt.
****                          // didn't say Yes here either

C:\Program Files\pl\bin>plcon -q
1 ?- writeln('****').
****

Yes                           // does say Yes as part of interaction
2 ?- halt.

C:\Program Files\pl\bin>      

そういうわけです。それに対処します。:) または、Jan と書いて、変更を依頼してください。:)

于 2012-09-17T10:13:10.237 に答える
1
girl(erin) :-
        girl(erin)
     -> write('it is true')
     ;  write('it is not true'). 

これは 2 つの理由で間違っています。Prolog は、左端のリテラルを取得して本文を解決しようとします。つまり、基本的には「エリンは女の子ですか?はい、もしエリンが女の子なら.エリンは女の子ですか?...」というループになります。

2 番目の理由は、2 つの異なるものを混合していることです。知識表現の部分を、それを使用する方法から分離しておくようにしてください。Prolog では、次のように言うだけです。

girl(erin)

そして、クエリ

?- girl(erin)

プロローグは「はい」と言うだけです。印刷したい場合、おそらく最も簡単な方法は述語を追加することです。

check_and_print(X) :- X, write(X), write(" is true").

使用している実装によっては、おそらく X の代わりに call(X) が必要です

コマンドプロンプトアウトについてはよくわかりません。結果が別の方法で返されると思われます。

于 2012-09-21T12:02:04.890 に答える