Время компиляции для «атомов» - PullRequest
0 голосов
/ 16 ноября 2018

Совершенно новый для пролога.Интересное путешествие в попытках изменить то, как я думаю, так что оцените любую помощь здесь.

Я пытаюсь утверждать факты для заранее определенного набора имен.Например, предположим, у меня есть набор людей [Алиса, Боб, ...] в одном файле.Я хотел бы утверждать факты об этих людях в других файлах, но хочу убедиться, что эти люди существуют, и это проверяется, когда факты загружаются / компилируются (?).

Например, предположим, что я нев списке нет 'chuck', и я делаю утверждение:

user: swipl app.pl

?- full_name(chuck, "Charlie Steel").

должно привести к ошибке.

Что такоелучший способ я могу это сделать?

1 Ответ

0 голосов
/ 16 ноября 2018

Итак, вот код, который я придумал:

person(deborah).
person(tony).

read_my_file(Filename) :-
    open(Filename, read, In),
    read_my_file1(In),
    close(In).

read_my_file1(In) :-
    read(In, Term),
    (  Term == end_of_file
    -> true
    ;  assert_or_abort(Term),
       read_my_file1(In)
    ).

assert_or_abort(Term) :-
    (  full_name(Person, Name) = Term
    ->  (  person(Person)
        -> assertz(full_name(Person, Name))
        ;  format(user, '~w is not a person I recognize~n', [Person])
        )
    ;  format(user, '~w is not a term I know how to parse~n', [Term])
    ).

Хитрость здесь заключается в том, чтобы использовать read/2 для получения термина Пролог из потока, а затем выполнить некоторые его детерминированные тесты, следовательно, вложенную условную структуру внутри assert_or_abort/1. Предположим, у вас есть входной файл, который выглядит следующим образом:

full_name(deborah, 'Deborah Ismyname').
full_name(chuck, 'Charlie Steel').
full_name(this, has, too, many, arguments).
squant.

Вы получите этот вывод:

?- read_my_file('foo.txt').
chuck is not a person I recognize
full_name(this,has,too,many,arguments) is not a term I know how to parse
squant is not a term I know how to parse
true.

?- full_name(X,Y).
X = deborah,
Y = 'Deborah Ismyname'.
...