2014-04-01 2 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

하지 않습니다. 이를 위해서는 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의 선언. 이것이 생략되면 프롤로그는 런타임에 선언되기 때문에 술어가 존재하지 않는다고 불평합니다. * 잘라 내기 !을 두 곳에서 사용하여 원치 않는 결정 성을 제거했습니다. * 스트림에서 수행 된 작업이 버그가 있어도 열려있는 스트림이 닫히도록 setup_call_cleanup/3을 사용하십시오.

코드가 여전히 비 결정적이므로 동일한 결과가 두 번 나타납니다. 이는 동일한 용어를 두 번 주장하는 코드 때문입니다.

희망이 도움이됩니다.

+0

대단히 고맙습니다. 또한 persistency.pl을 사용했으며 제대로 작동합니다. –

1

이 적절한주의없이 프롤로그에서 악용 될 수있는 좋은 예입니다.

내 이름은 'a,b).\n:- initialization(dobadthings). %'입니다. 그래서 경우 output.txt는

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

내장 된 술어 read/1 전체 프롤로그 구문을 허용처럼 보일 것이다. 불행하게도, read/1에 analogon는 write/1,도 writeq/1 (가까이) 오히려되지 않습니다 : variable_names/1 같은

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

추가 옵션 변수 이름이 유지되어야한다 특정 상황에 도움이 될 수 있습니다.


또 다른 (잠재적 인) 문제

는 SWI에 고유 한 것으로 보인다 및 특정 문자의 일부 특정 해석을 수행하는 특이한 writef/1의 사용이다. 어쨌든 좋은 아이디어는 아닙니다. 간단한 write/1은 같은 값일 것입니다.

관련 문제