我知道:
尼克= 2 *凯特
(Kate Lea)= 2 *尼克
(Chris Nick)= 2 *(Kate Lea)
阿什利= 24
Ashley Kate Lea = 2 *(Chris Nick)
尼克= 2 *凯特
(Kate Lea)= 2 *尼克
(Chris Nick)= 2 *(Kate Lea)
阿什利= 24
Ashley Kate Lea = 2 *(Chris Nick)
取消一些后,我发现:
Ashley = 12 * Kate =>凯特= 2
Lea = 3 * Kate => Lea = 6
尼克= 2 *凯特=>尼克= 4
克里斯= 6 *凯特=>克里斯= 12
我试过这个:
:- use_module(library(clpfd)). ages(As) :- As = [Ashley,Lea,Nick,Chris,Kate],Ashley #= 24,12 * Kate #= Ashley,Lea #= 3*Kate,Nick #= 2*Kate,Chris #= 6*Kate.
输出:
Ashley = 24,Chris = 12,Kate = 2,Lea = 6,Nick = 4
上面的解决方案工作正常,但老师告诉我,我不能使用取消.我有点困惑,因为没有取消它不起作用.
:- use_module(library(clpfd)). ages(As) :- As = [Ashley,Lea + Kate #= 2 * Nick,Chris + Nick #= 2 * (Kate + Lea),Nick #= 2 * Kate,Ashley + Kate + Lea #= 2*(Nick + Chris).
输出:
Ashley = 24,Lea+Kate+24#=2*Nick+2*Chris,Chris+Nick#=2*Lea+2*Kate,Lea+Kate#=2*Nick,2*Kate#=Nick
有任何想法吗?
解决方法
如果您按原样调用年龄/ 1,则会得到剩余目标(有关详细信息,请参阅
CLP(FD)文档)作为答案:
?- ages(As). As = [24,_G1642,_G1645,_G1648,_G1651],_G1642+ -2*_G1645+ -2*_G1648+_G1651#= -24,-2*_G1642+_G1645+_G1648+ -2*_G1651#=0,_G1642+ -2*_G1645+_G1651#=0,2*_G1651#=_G1645.
为了获得实际数字,您必须限制数字的范围并随后标记.由于已知没有人达到200年,因此0至200的年龄限制似乎是合理的.然后您的查询提供实际数字作为答案:
?- ages(As),As ins 0..200,label(As). As = [24,6,4,12,2].
这解决了您的直接问题.但是,我想补充两点.首先,它产生更清晰可读的代码,以将域限制和标记部分与描述实际关系的谓词分开.其次,它有助于结果的可读性在列表中具有成对的名称年龄.为了说明这些点,我们定义一个谓词年龄2/1,它调用核心关系age2_ / 2,然后限制和标记年龄.核心关系将年龄与名称分开,并在第二个列表中提供所述年龄,毕竟这些是您要标记的变量.这允许您在调用谓词年龄2/1的单个列表中具有任意复杂的术语.随后,您可以像在年龄/ 1中一样发布约束.将这些想法放在一起可能看起来像这样:
ages2(NAs) :- ages2_(NAs,As),label(As). ages2_(NAs,As) :- NAs = [ashley-Ashley,lea-Lea,nick-Nick,chris-Chris,kate-Kate],As = [Ashley,Ashley + Kate + Lea #= 2*(Nick + Chris). ?- ages2(As). As = [ashley-24,lea-6,nick-4,chris-12,kate-2].
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。