1. 脑筋急转弯
常见的,prolog会被认为是解决脑筋急转弯的利器
在逻辑问题上比其他语言更强吗?下面我展示几个例子试图弄清这个问题
2. 言灵岛
就是只能说真话和假话的小岛,很多和逻辑有关得书中都会提到。最原始的版本被叫做 Knights and Knaves
设定:
作为冒险者的你无意中踏上了一座诡异的小岛,岛上的人天生会被分为只会说谎言(山间土匪)和只会说实话(圣光骑士)两种
需要使用CLP约束库
use_module(library(clpb)).
sat
约束规则的用法比较简单,~
表示false约束,*
表示且,+
表示或
2.1. 场景1
你遇到了两个岛民,A,B,A说:“我们两个都说假话!或者他(B)会说真话”
翻译成约束:
sat(A =:= ~A + B).
推理结果秒出
A = B, B = 1.
2.2. 场景2
A说“我只说假话,B只说真话”
翻译为约束代码:
-? sat(A =:= ~A * B).
A = B, B = 0.
2.3. 场景3
你遇到了三个岛民,A说:“我们都说假话”,B说“我们中有一个人是真话的”
这里需要一个
card
语句
card([1],[A,B,C])
=> abc中有一个为真
card([1,2],[A,B,C])
===card([1],[~A,~B,~C])
=> abc中最多两个为真,或abc中至少一个为假
代码:
?- sat(A =:= (~A * ~B * ~C)), sat(B =:= card([1],[A,B,C])).
A = C, C = 0,
B = 1.
2.4. 场景4
这个例子来自于 百度知道 - 有一个岛上住着两种人,一种是说真话的人,一种是说假话的人。
且,标榜最佳答案的选手还是错的...
代码
?- sat(A =:= ~B * ~C), sat(B =:= B), sat(C =:= ~B).
A = 0,
sat(B=\=C)
即,A肯定是说谎者,而BC无法确定,同时BC是不同的