1

Prolog で変数の型を知る方法はありますか? 私はコードを持っています

test:- 
    writeln('Please enter the absolut file name :'),
    read(FileName),
    write('Opening file '),
    write(FileName),nl,
    open(FileName,read,Stream),
    read_file(Stream,Lines),
    close(Stream),
    parseLines(Lines).


% used on reading the text file 
read_file(Stream,[]) :-
    at_end_of_stream(Stream).
% used on reading the text file 
read_file(Stream,[X|L]) :-
    \+ at_end_of_stream(Stream),
    read(Stream,X),
    read_file(Stream,L).

parseLines(Lines):-
%primele 2 linii contin lista cu barbatii si list cu femeile iar 
%restul liniilor contin preferintele acestora
    Lines=[LB|[LF|LPrefs]],
    writeln(LB),
    atom_length(LB,2).

そして、エラーが発生します(テストの実行時)

ERROR: [Thread pdt_console_client_0_Default Process] atom_length/2: Type error: `list' expected, found `man([m1,m2])'

入力テキスト ファイルには、

man = {m1, m2}.
women = {w1, w2}.

m1: w1 > w2.
m2: w1 > w2.
w1: m1 > m2.
w2: m1 > m2.

私はそのファイルを解析しようとしていますが、ファイルから読み取った行にあるものが string,atoms ではないなど、何を試してもそのエラーが発生します。これを修正するために何をすべきかわかりません。

PSファイルを高速/単純に解析する方法についてのアイデアはありますか? 問題の入力を解析することは、問題を解決することよりもはるかに難しいというのは奇妙に感じます。

ありがとう。

編集:複合述語が見つかりました。ファイルから読み取られた行は複合用語です。Edit2: 私の目標は、そのファイルのデータを読み取り、それをアサートすることです。安定した結婚の問題を解決したいのですが、このファイル形式から入力を読み取るこの部分を理解できません。

Edit3:次のような行を持つ他の入力ファイルがあります。

alan: christine > tina > zoe > ruth > sarah.

この行は、複数の > 演算子のために read_file_to_terms で用語として読み取ろうとすると失敗するため、すべての入力が有効であるとは限りません Prolog

4

1 に答える 1

2

質問に [swi-prolog] というタグを付け、ファイルに有効な Prolog 用語が含まれているため、read_file_to_terms /3 を使用して、1 回の呼び出しでリストを読み込むことができます (このヒントは PS 部分用です)。その後、用語のリストを処理する必要があります: parseLines/1 は役に立ちません。リスト処理の例として、ロードされた各用語を表示します。

?- read_file_to_terms('/home/carlo/x.txt',L,[]), maplist(writeln, L).
man={m1,m2}
women={w1,w2}
m1:w1>w2
m2:w1>w2
w1:m1>m2
w2:m1>m2
L = [man={m1, m2}, women={w1, w2}, m1:w1>w2, m2:w1>w2, w1:m1>m2, w2:m1>m2].

編集 {} は「セットコンストラクター」という名前だと思います。これは、複合体の奇妙な形です。

?- write_canonical({a,b,c}).
{}(','(a,','(b,c)))

univ を使用して引数のリストを取得できます

?- {a,b,c} =.. X.
X = [{}, (a, b, c)].

以前の編集のバグ

=..{} は、化合物というよりも前置詞と後置詞の両方op(xf,,({))の演算子に似ているため (つまり、何らかの方法で andを結合するop(fx,,(})))、あまり関連性がないように思われます。

私の知る限り、「セット」をリストに変換するには、次のようなものが必要です

setcons_to_list(S, L) :-
    S =.. [{}, E] -> andexpr_to_list(E, L) ; L = [].

andexpr_to_list((E,Es), [E|Ts]) :-
    !, andexpr_to_list(Es, Ts).
andexpr_to_list(E, [E]).

テスト

?- setcons_to_list({},L).
L = [].

?- setcons_to_list({1,2,3,4},L).
L = [1, 2, 3, 4].

もっと編集する

Prolog オペレーターは「構成可能」であり、パーサーにその設定リストについて指示することができます。ソースにop宣言を追加します:- op(10,xfy,(>)).。プロンプトを使用したサンプル

?- op(10,xfy,(>)).
true.

?- X = (alan: christine > tina > zoe > ruth > sarah),write_canonical(X).
:(alan,>(christine,>(tina,>(zoe,>(ruth,sarah)))))
X = alan:christine>tina>zoe>ruth>sarah.

注意: 定義済みの結合性の変更は注意して行う必要があります。それ以外の場合、 DCG を使用してより一般的なパーサーを作成する場合は、この他の回答が役立ちます。

于 2013-01-08T16:58:58.173 に答える