Прочтите весь факт из внешнего файла

54
4

В соответствии с приведенным ниже, когда пытаюсь утверждать факт, я имею тип ошибки, вызываемой ожидаемой, я думаю, что вставка фактов по строкам происходит успешно. Но asserta не работает хорошо. Несмотря на это, я попытался преобразовать в строку using (string_codes (? 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.

спросил(а) 2014-04-01T03:05:00+04:00 6 лет, 3 месяца назад
1
Решение
68

Вы пытаетесь написать, а затем прочитать условия Prolog. Для этого вы должны использовать комбинацию write_term/3 и read_term/3.

Поскольку read/1 требует, чтобы вы добавили точку в конец входного слова, я добавил параметр fullstop/1 в write_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 чтобы гарантировать, что открытые потоки закрываются, даже если операции, выполняемые в потоке, являются ошибками.

Обратите внимание, что код по-прежнему не является детерминированным, что дает вам тот же результат дважды. Это связано с тем, что код содержит два одинаковых условия.

Надеюсь это поможет!

ответил(а) 2014-04-04T23:57:00+04:00 6 лет, 3 месяца назад
55

Это хороший пример, когда code-injection можно использовать в Prolog без надлежащего ухода.

Меня зовут 'a,b).\n:- initialization(dobadthings). %' 'a,b).\n:- initialization(dobadthings). %'. Таким образом output.txt будет выглядеть так:

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

Встроенный предикат read/1 принимает полный синтаксис Prolog. К сожалению, аналогом для read/1 не является write/1, а writeq/1 (что близко), а скорее:


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

Дополнительные параметры, такие как variable_names/1 могут помочь в конкретной ситуации, когда имена переменных должны быть сохранены.

Другой (потенциальной) проблемой является использование уникальной записи writef/1 которая кажется уникальной для SWI и делает определенную интерпретацию определенных символов. В любом случае, это не очень хорошая идея. Простая write/1 будет иметь одинаковую ценность.

ответил(а) 2014-08-24T18:11:00+04:00 5 лет, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема