Prolog:单引号和双引号的不同行为

时间:2015-12-11 01:47:08

标签: prolog portability double-quotes prolog-assert

我对Prolog很陌生,我偶然发现了一些我不理解的事情。

这是我的代码:

let currentButton2Frame = button2.layer.presentationLayer()!.frame
button2.layer.removeAllAnimations()
button2.frame = currentButton2Frame

要更新数据库中的用户信息, frame执行以下三个步骤:

  1. 使用:- dynamic user/3. user('id', 'Name', 20). changeAge(Id, NewAge) :- user(Id, Name, _), retract(user(Id,_,_)), assert(user(Id,Name,NewAge)). 查找正确的记录。
  2. 使用changeAge/2从数据库中删除一条匹配的记录。
  3. 使用user/3将新的更新记录插入数据库。
  4. 这是我的控制台输出:

    retract/1

    为什么单引号会给我assert/1(第2行) 当双引号给我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. (第4行)?

2 个答案:

答案 0 :(得分:2)

<强> TL; DR <子> <子> 1 阅读问题的this answer &#34; What is the difference between ' and " in Prolog?&#34;

TL; DR 2 目标'id' = "id"成功iff Prolog标志double_quotes设置为atom

可以使用double_quotes在运行时设置Prolog flag set_prolog_flag/2

  • ?- set_prolog_flag(double_quotes, chars).

    ?- 'id' = "id".
    false.
    
  • ?- set_prolog_flag(double_quotes, codes).

    ?- 'id' = "id".
    false.
    
  • ?- set_prolog_flag(double_quotes, atom).

    ?- 'id' = "id".
    true.
    

有关详细信息,请参阅&{34; SICStus Prolog manual&#34; {/ p>上的Strings as lists页面。

答案 1 :(得分:2)

让我们说一些用户在数据库中获得了相同ID的多条记录;可能具有潜在用途的东西,比如,如果人们可能有多个名字......无论哪种方式,这个答案都不是关于使建模部分正确,而是关于的技术方面!的因人而异。

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

让我们初始化数据库,并改变一些年龄&#34; : - )

?- 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,_)].

更糟糕! in:8个不同的地面记录。 out:2个不同的非地面记录。

底线: 小心谨慎处理&#34;附加到的警告标志!