2014-04-01 40 views
1

根據下面的內容,當試圖斷言事實時,我有可預期的類型錯誤可調用,我認爲逐行插入事實成功發生。但是,asserta不能很好地工作。儘管如此,我想轉換爲使用字符串(string_codes(?字符串?代碼))或插入的代碼行,但它不會成功從外部文件中讀取全部事實

 
 
start:- 
    writeToFile, 
    readFromFile, 
    usereduc(C,D), 
    writef(C), 
    writef(D). 

writeToFile:- 
    writef('What is your Name'),nl, 
    read(Name), 
    writef('What is your country'),nl, 
    read(Country), 
    writef('What is your education'),nl, 
    read(Education), 
    open('output.txt',write,Out), 
    write(Out,usercountry(Name,Country)),nl(Out), 
    write(Out,usereduc(Name,Education)), 
    close(Out). 


readFromFile:- 
    open('output.txt',read,In), 
    repeat, 
    read_line_to_codes(In,X),nl, 
    readfactsFromfile(X),asserta(X), 
    close(In). 


readfactsFromfile(end_of_file). 
readfactsFromfile(X):- 
    writef(X), 
    string_codes(S, X), 
    asserta(S),!, 
    fail. 
 

回答

2

您正在嘗試寫,然後回讀Prolog的條款。爲此,您應該使用組合write_term/3read_term/3

由於read/1要求您在輸入項的末尾添加一個點,所以我添加了選項fullstop/1write_term/3。然後,工作代碼如下:

:- dynamic(usereduc/2). 

start:- 
    writeToFile, 
    readFromFile, 
    usereduc(C,D), 
    writef(C), 
    writef(D). 

writeToFile:- 
    writef('What is your Name'),nl, 
    read(Name), 
    writef('What is your country'),nl, 
    read(Country), 
    writef('What is your education'),nl, 
    read(Education), 
    setup_call_cleanup(
    open('output.txt',write,Out), 
    (
     write_term(Out,usercountry(Name,Country), [fullstop(true)]),nl(Out), 
     write_term(Out,usereduc(Name,Education), [fullstop(true)]) 
    ), 
    close(Out) 
). 

readFromFile:- 
    setup_call_cleanup(
    open('output.txt',read,In), 
    (
     repeat, 
     read_term(In, X, []), 
     readfactsFromfile(X),asserta(X), ! 
    ), 
    close(In) 
). 

readfactsFromfile(end_of_file):- !. 
readfactsFromfile(X):- 
    asserta(X),!, 
    fail. 

請注意,我已經添加到您的代碼下面的其他改進: *的usereduc/2聲明爲動態謂詞。如果這被遺漏了,Prolog會抱怨謂詞不存在,因爲它在運行時被斷言。 *刪除不需要的決定性使用在兩個點的剪切!。 *使用setup_call_cleanup/3可確保即使在流上執行的操作有問題,打開的流也會關閉。

注意代碼仍然是非確定性的,給你兩次相同的結果。這是由於代碼斷言兩次相同的術語。

希望這會有所幫助!

+0

非常感謝你,我也用persistency.pl,它看起來很好 –

1

這是一個很好的例子,其中可以在沒有適當注意的情況下在Prolog中被利用。

我的名字是'a,b).\n:- initialization(dobadthings). %'。所以output.txt中會像

usercountry(a,b). 
:- initialization(dobadthings). %whatevercountry). 
userreduc(a,whatevere). 

內置謂詞read/1接受全Prolog的語法。 不幸的是,analogon到read/1write/1,也不writeq/1(這是接近),而是:

write_term(T, [quoted(true)]). 

variable_names/1其他選項可以在特定情況下的變量名應該保留的幫助。


另一個(潛在的)問題是特質writef/1的使用,這似乎是唯一的SWI和做某些字符的一些具體的解釋。無論如何,使用它並不是一個好主意。一個簡單的write/1將具有相同的值。