Question

According to the below when try to assert the fact I have type error callable expected , I think the insertion o facts line by line happens successfully.But,the asserta does not work well.Despite that,I tried to convert to string using ( string_codes(?String, ?Codes) ) or insert as line of code but it does not success

    
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. 

Was it helpful?

Solution

You are trying to write and then read back Prolog terms. For this you should use the combination write_term/3 and read_term/3.

Since read/1 requires you to add a dot to the end of the input term, I have added the option fullstop/1 to write_term/3. The working code then looks as follows:

:- 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.

Notice that I have added the following additional improvements to your code: * The declaration of usereduc/2 as a dynamic predicate. If this is left out Prolog complains that the predicate does not exists, since it is asserted at run time. * Removed unwanted determinism using the cut ! at two spots. * Use of setup_call_cleanup/3 to ensure that opened streams get closed even if the operations performed on the stream are buggy.

Notice that the code is still non-deterministic, giving you the same result twice. This is due to the code asserting the same terms twice.

Hope this helps!

OTHER TIPS

This is a good example where can be exploited in Prolog without proper care.

My name is 'a,b).\n:- initialization(dobadthings). %'. So output.txt will look like

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

The built-in predicate read/1 accepts full Prolog syntax. Unfortunately, the analogon to read/1 is not write/1, nor writeq/1 (which is close) but rather:

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

Additional options like variable_names/1 may help in a specific situation where variable names should be retained.


Another (potential) problem is the usage of the idiosyncratic writef/1 which seems to be unique to SWI and does some specific interpretation of certain characters. In any case, not a good idea to use. A simple write/1 would be of same value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top