如何从prolog中的csv文件生成规则?

时间:2016-05-22 21:19:53

标签: prolog

我不熟悉Prolog,但我需要帮助使用属性值对从CSV数据生成规则。

我试图从下表中生成规则,但对我来说很难。

obj height hair eyes class
o1  short  blond blue  c1
o2  short blond brown c2
o3  tall   red     blue     c1
.
.
.etc.

我试图找到关于C1的第一条规则,为所有属性值对计算所有p(C1|av),然后从set中删除覆盖的对象,为每个类重复这些步骤。

1 个答案:

答案 0 :(得分:0)

不是100%确定你要做什么,但我认为你正在尝试读取TSV(tab-seperated?)文件并根据值生成子句。

例如,以下TSV文件......

ID    a1    a2
o1    abc   def
o2    bcd   efg

......代表事实......

a1(o1, abc)
a1(o2, bcd)
a2(o1, def)
a2(o2, efg)

以下程序将读取制表符分隔的文件并生成此类子句的列表。这是我的输入文件...

id  height  hair    eyes    class
o1  short   blond   blue    c1
o2  short   blond   brown   c2
o3  tall    red blue    c1

以下代码将以此格式读取文件(对象ID应该是第一列)并生成子句...

% Exmaple clause to read a file and print out facts to the console.
% Instead of printing, you could do whatever you like with them (assert them into WM for example)
example :-
    build_facts_from_file('c:\\tmp\\data.tsv', FACTS),
    writeln(FACTS).

% build_facts_from_file(FILENAME_IN, FACTS_OUT).
% Reads the file and outputs a list of facts.
build_facts_from_file(FILENAME, FACTS) :-
    open(FILENAME, read,S),
    read_tsv(S,[HEADER | RECORDS]),
    close(S),
    build_records(HEADER, RECORDS, FACTS).

% read_tsv(INPUT_STREAM_IN, LINES_OUT)
% Read tab-seperated values from the stream S into a list (one element per line)
read_tsv(S, []) :-
    % Stop if EOF
    at_end_of_stream(S), !.

read_tsv(S, [L | T]) :-
    % Read whole line as character codes
    read_line_to_codes(S, CODES),
    % Translate the line into a list of atoms
    translate_tsv(CODES, [], L),
    % Read the other lines
    read_tsv(S, T).

% translate(CHARACTER_CODE_LIST_IN, ATOM_SO_FAR_IN, ATOMS_OUT).
% Gets a line, splits it on TAB characters and turns each element into an atom
translate_tsv([], [], []) :- !. 
    % Stopping condition when tab was at end of line, but no extra element  
translate_tsv([], ATOM_CHARS, [ATOM]) :-
    % Stopping condition when non-tab was at end of line, 
    % turn list of codes for the atom found so far into an atom
    atom_chars(ATOM, ATOM_CHARS).
translate_tsv([9 | CODES], ATOM_CHARS, [ATOM | ATOMS]) :- !,
    % Tab found, turn ATOM_CHARS into ATOM and start building the next atom
    atom_chars(ATOM, ATOM_CHARS),
    translate_tsv(CODES, [], ATOMS).
translate_tsv([CODE | CODES], ATOM_CHARS, ATOMS) :- !,  
    % Non-tab character found, appent CODE to the end of ATOM_CHARS and keep going
    append(ATOM_CHARS, [CODE], TMP_ATOM_CHARS),
    translate_tsv(CODES, TMP_ATOM_CHARS, ATOMS).

% build_records(HEADER_IN, RECORDS_IN, FACTS_OUT)
% Process each element in RECORDS_IN to create FACTS_OUT
build_records(_, [], []).
    % Stopping case, no records left to build
build_records(HEADER, [RECORD | RECORDS], FACTS) :-
    % Build facts for all the other records
    build_records(HEADER, RECORDS, FTMP1),
    % Build facts for this record
    build_fact(HEADER, RECORD, FTMP2),
    % Add lists together
    append(FTMP1, FTMP2, FACTS).

% build_fact(HEADER_IN, ATTRIBUTES_IN, FACTS_OUT)   
% Builds clauses for each attribute - strips out the object ID (assumed to be first attribute)
% and calls build_fact/4 to do the work
build_fact([_ | HEADER], [ID | ATTRIBUTES], FACTS) :-
    build_fact(ID, HEADER, ATTRIBUTES, FACTS).

% build_fact(OBJECT_ID_IN, PROPERTY_NAMES_IN, VALUES_IN, FACTS_OUT) 
build_fact(ID, [PROP | PROPS], [VALUE | VALUES], [FACT | FACTS]) :-
    % create term for the fact
    FACT =.. [PROP, ID, VALUE],
    % build the rest
    build_fact(ID, PROPS, VALUES, FACTS).

build_fact(_, [], [], []).
    % Stopping condition

示例输出:

1 ?- example.
[height(o3,tall),hair(o3,red),eyes(o3,blue),class(o3,c1),height(o2,short),hair(o2,blond),eyes(o2,brown),class(o2,c2),height(o1,short),hair(o1,blond),eyes(o1,blue),class(o1,c1)]

希望这有帮助