Пролог: Различное поведение одинарных и двойных кавычек
Я довольно новичок в Прологе и наткнулся на то, чего не понимаю.
Это мой код:
:- dynamic user/3.
user('id', 'Name', 20).
changeAge(Id, NewAge) :-
user(Id, Name, _),
retract(user(Id,_,_)),
assert(user(Id,Name,NewAge)).
Чтобы обновить информацию о пользователе в базе данных,changeAge/2
выполняет эти три шага:
- Поиск правильной записи, используя
user/3
, - Удалить одну подходящую запись из базы данных, используя
retract/1
, - Вставьте новую обновленную запись в базу данных, используя
assert/1
,
Это мой консольный вывод:
1 ?- user('id', _, Age).
Age = 20.
2 ?- changeAge('id', 25).
true.
3 ?- user('id', _, Age).
Age = 25.
4 ?- changeAge("id", 30).
false.
5 ?- user('id', _, Age).
Age = 25.
Почему одинарные кавычки дают мне true
(строка 2), когда двойные кавычки дают мне false
(строка 4)?
2 ответа
TL; DR1: Прочтите этот ответ на вопрос "В чем разница между" и "Пролог"?".
TL; DR2: цель 'id' = "id"
успешно, если флаг Prolog double_quotes установлен в atom
,
Флаг Пролог double_quotes
может быть установлен во время выполнения с помощью set_prolog_flag/2
:
?- set_prolog_flag(double_quotes, chars).
?- 'id' = "id".ложь
?- set_prolog_flag(double_quotes, codes).
?- 'id' = "id".ложь
?- set_prolog_flag(double_quotes, atom).
?- 'id' = "id".правда
Для получения дополнительной информации прочитайте страницу руководства SICStus Prolog " Строки как списки"!
Допустим, некоторые пользователи получили несколько записей для одного и того же идентификатора в базе данных; что-то, что может иметь потенциальное применение, скажем, если у людей может быть более одного имени... в любом случае, этот ответ не о правильной части моделирования, а о технических аспектах /questions/tagged/prolog-assert! YMMV.
:- dynamic(user/3).
init_db :-
retractall(user(_,_,_)),
maplist(assert, [user(i,n,1),user(i,n,2),user(i,m,1),user(i,m,2),
user(j,n,1),user(j,n,2),user(j,m,1),user(j,m,2)]).
changeAge(Id, NewAge) :-
user(Id, Name, _),
retract(user(Id,_,_)),
assert(user(Id,Name,NewAge)).
Давайте инициализируем базу данных и "изменим возраст":-)
?- init_db, (changeAge(i,6) ; changeAge(j,7)), false.
false.
?- findall(user(Id,Name,Age), user(Id,Name,Age), DB).
DB = [user(i,m,6),user(i,m,6),user(i,m,6),user(i,m,6),
user(j,m,7),user(j,m,7),user(j,m,7),user(j,m,7)].
Плохой! в: 8 различных записей. out: 2 разных записи, каждая из которых имеет кратность 4.
Давайте восстановим исходные факты, а затем используем changeAge/2
немного по-другому:
?- init_db, changeAge(_,_), false.
false.
?- findall(user(Id,Name,Age), user(Id,Name,Age), DB).
DB = [user(i,m,_),user(i,m,_),user(i,m,_),user(i,m,_),
user(j,m,_),user(j,m,_),user(j,m,_),user(j,m,_)].
Еще хуже! в: 8 различных наземных записей. out: 2 разных незаземленных записи.
Итог: будьте внимательны с предупреждающим знаком "обращайтесь с осторожностью", прикрепленным к прологу-заявить!