我的用于解决 3 壶水难题的序言程序有什么问题?

2023-12-02

任何人都可以找到为什么我在这段代码中无法通过“go”得到任何真正的答案吗?例如,我写go(7,3,l)我认为它应该将 3 升水转移到第二个水罐中,但根据序言,这是错误的。怎么了?

:- dynamic go/3.
:- dynamic cur_state/1,init/5.
:- dynamic end_state/1, final/5.

cur_state(State):-State = state(10,0,0,7,l).
end_state(State):-State = state(0,3,3,0,r).

pour(state(D1,D2,D3,n,l),move(D,C,r),state(D,C,D3,n,r)) :-
        D is D1-n,
        C is D2+n.
pour(state(D1,D2,D3,n,r),move(D,C,l),state(D,C,D3,n,l)) :-
        D is D1-n,
        C is D2.
pour(state(D1,D2,D3,n,l),move(D,C,r),state(D,D2,C,n,r)) :-
        D is D1-n,
        C is D3+n.
pour(state(D1,D2,D3,n,l),move(D,C,r),state(D1,D,C,n,r)) :-
        D is D2-n,
        C is D3+n.
pour(state(D1,D2,D3,n,r),move(D,C,l),state(D1,D,C,n,l)) :-
        D is D2-n,
        C is D1+n.
pour(state(D1,D2,D3,n,r),move(D,C,l),state(D1,D,c,n,l)) :-
        D is D2-n,
        C is D3.
pour(state(D1,D2,D3,n,l),move(D,C,r),state(C,D2,D,n,r)) :-
        D is D3-n,
        C is D1.
pour(state(D1,D2,D3,n,r),move(D,C,l),state(D1,C,D,n,l)) :-
        D is D3-n,
        C is D2+n.
pour(state(D1,D2,D3,n,r),move(D,C,l),state(C,D2,D,n,l)) :-
        D is D3-n,
        C is D1+n.

carry(7,0).
carry(3,0).
carry(10,0).
carry(7,0).
carry(7,3).

legal(10,X,Y):-X+Y<10.
legal(X,Y,Z):-X+Y+Z<10.
legal(X,7,Y):-X+Y=<3.
legal(X,Y,3):-X+Y=<7.

newstate(state(D1,D2,D3,n,l),state(D11,D22,D33,n1,r)):-
        carry(M,C),
        M=<7,C=<3,
        D22 is D2+n,
        D11 is D1-n,
    D3 is D33,
    n1 is n,
        D2=<7,D1=<10,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,n,r),state(D11,D22,D33,n1,l)):-
        carry(M,C),
        M=<10,C=<100,
        D11 is D1-n,
    D22 is D2,
    D33 is D3,
        D1=<10,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,n,l),state(D11,D22,D33,n1,r)):-
        carry(M,C),
        M=<10,C<3,
        D11 is D1-n,
        D33 is D3+n,
    D22 is D2,
        D1=<10,D3=<3,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,n,r),state(D11,D22,D33,n1,l)):-
        carry(M,C),
        M=<7,C=<3,
        D22 is D2-n,
        D33 is D1+n,
        D11 is D1,
    D2=<7,D1=<10,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,n,l),state(D11,D22,D33,n1,r)):-
        carry(M,C),
        M=<7,C=0,
        D22 is D2-n,
        D33 is D3+n,
        D11 is D1,
    D2=<7,D3=<3,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,n,r),state(D11,D22,D33,n1,l)):-
        carry(M,C),
        M=<7,C=<100,
        D22 is D2-n,
    D33 is D3,
    D11 is D1,    
    D2=<7,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,n,r),state(D11,D22,D33,n1,l)):-
        carry(M,C),
        M=<3,C=<7,
        D22 is D2+n,
        D33 is D3-n,
        D11 is D1,
    D3=<3,D2=<7,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,n,r),state(D11,D22,D33,n1,l)):-
        carry(M,C),
        M=<3,C=<100,
        D11 is D1+n,
        D33 is D3-n,
        D22 is D2,
    D3=<3,D1=<10,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,n,l),state(D11,D22,D33,n1,r)):-
        carry(M,C),
        M=<3,C=<100,
        D33 is D3-n,
        D22 is D2,
    D11 is D1,  
    D3=<3,
    legal(D1,D2,D3).


eisodos(_):- cur_state(State),write(State),nl.

init(S1,S2,S3,S4,S5):-assert(cur_state(State):-State = state(S1,S2,S3,S4,S5)),write('Arxikh:'),
   write(state(S1,S2,S3,S4,S5)),retractall(init(S1,S2,S3,S4,S5)),nl.

final(S1,S2,S3,S4,S5):-assert(end_state(State):-State = state(S1,S2,S3,S4,S5)),write('Telikh:'),
   write(state(S1,S2,S3,S4,S5)),retractall(init1(S1,S2,S3,S4,S5)),nl.

go(Move1,Move2,Move3):-cur_state(State),newstate(State,NextState),
        pour(State,move(Move1,Move2,Move3), NextState),
        retractall(cur_state(State):-State = state(_,_,_,_,_)),asserta(cur_state(NextState)),
        ((end_state(NextState),write('Bravo!!!!')) ;(write(' ---*Eiste sthn katastash --- :'),write(NextState))),nl.

扩展@Mog的答案,如果你想找到最短的解决方案,我建议使用迭代深化。以下基于@Mog发布的代码(因此解决了与OP发布的问题略有不同的相同问题)。当我们想要描述一个(动作)列表时,DCG 表示法很方便:

solution(Path) :- length(Path, _), phrase(path([0-3, 0-5, 8-8]), Path).

path(State) --> { equivalent(State, [0-3, 4-5, 4-8]) }.
path(State0) --> [From-To],
        { move(State0, State), State = [_-From, _-To, _] },
        path(State).

equivalent(State1, State2) :- forall(member(X, State1), member(X, State2)).

move(State, [NewX-From, NewY-To|NewRest]) :-
    select(X-From, State, Rest),
    X \== 0,
    select(Y-To, Rest, NewRest),
    Fillable is To - Y,
    ToFill is min(X, Fillable),
    NewY is Y + ToFill,
    NewX is X - ToFill.

示例查询:

?- solution(Ps).
Ps = [8-5, 5-3, 3-8, 5-3, 8-5, 5-3, 3-8] .
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我的用于解决 3 壶水难题的序言程序有什么问题? 的相关文章

  • Prolog 时间重叠问题

    假设我有这个知识库 free ann slot time 8 0 time 9 0 free ann slot time 10 0 time 11 0 free bob slot time 7 0 time 8 30 free bob sl
  • 如何提高词法分析效率?

    在解析一个 3 GB 的大文件时DCG https www metalevel at prolog dcg 效率很重要 我的词法分析器的当前版本主要使用 or 谓词 2 http www swi prolog org pldoc doc f
  • AllegroGraph 检查现有三元组

    我正在使用 AllegroGraph 4 我有一个三元组存储 并且只有在新的三元组尚不存在时我才会尝试添加它们 这是我的 Prolog 查询 select news alfas news a news tst has annotation
  • 在 Prolog 中表达“交换性”的替代方案?

    作为一个Prolog的初学者 我发现Prolog中的交换表达式非常不直观 例如 如果我想表达 X 和 Y 属于一个家庭 例如 family X Y married X Y relative X Y father son X Y 我还应该在定
  • YAP Prolog 中的正向链接?

    我需要在某些 Prolog 问题中使用前向链接器 我想避免使用普通元解释器从头开始实现它 但如果没有其他选项可用 这就是我必须要做的 因为使用元解释器执行此操作会很慢 而且我我确信应该有一些好的实现 有人知道 YAP 或 SWI Prolo
  • Prolog 管线任务

    我有一项任务是在序言中制作一张简化的地铁地图 其中一部分要求制定一项规则来检查两个车站是否在同一条线上 我有一条规则 但它似乎不起作用 这就是我到目前为止所拥有的 adjacent nh lg central 4 adjacent lg o
  • 井字游戏的极小极大

    我正在尝试用简单的极小极大算法来解决井字游戏 简单 但应该涵盖很多语言 到目前为止我所拥有的 该板表示为 9 个 未绑定 变量的数组 这些变量可以设置为x or o 获胜条件基本上是 win Player X1 X2 X3 X1 Playe
  • 非成员规则在 Prolog 中无法按预期工作

    我正在尝试在 Prolog 中创建一个迷宫程序 其目的是找到一条从迷宫起点到迷宫中心点 m 的路线 迷宫由使用四种颜色之一连接的正方形组成 蓝色 绿色 紫色或橙色 从起点到中心的路线遵循四种颜色的重复图案 我创建了以下代码 link2 A
  • 在 Prolog 中动态拆分列表

    我从序言开始几周 但我看到了更深入的操作列表的递归谓词的构造 我的问题是 是否可以构建一个谓词 将给定列表拆分为给定数量的其他列表 比如我想象的 split H T NumberLists Lists 递归实现 split 1 2 3 4
  • Prolog 实现 and/2、or/2、nand/2、nor/2、xor/2 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想在序言中实现以下谓词并将它们用于真值表 and 2 or 2 nand 2 nor 2 xor 2 也许有人可以告诉我如何实现和
  • 在 prolog 中读取用户输入的字符串

    我是 Prolog 初学者 我正在使用 swi prolog 刚刚开始使用它 我需要将用户输入字符串拆分到列表中 我尝试了以下代码 但出现错误 指出 在子句正文中完全停止 无法重新定义 2 write Enter the String nl
  • 列表中的连续元素

    我正在阻止一个谓词来编码Prolog 我需要对两个谓词进行编码 如果我打电话 u a b c d e f X 它会给X a b X b c X c d 如果我打电话 v a b c d e f X 它会给X a b X c d X e f
  • SWI Prolog 使用的检查优化会发生什么情况?

    去引用SICStus Prolog 手册 https sicstus sics se sicstus docs 3 12 9 html sicstus Occur html 逻辑编程背后的通常数学理论禁止 创建循环项 规定发生检查应该是 每
  • F# 和模糊逻辑

    我知道这可能听起来很奇怪 但我想知道 Microsoft Visual F 正在进入的这个新世界中的一件事 这种语言有很多应用 我要学习 关于解析 函数式编程 结构化编程 但是人工智能呢 模糊逻辑有什么应用吗 F 是一种适合模糊逻辑应用程序
  • 如何找到排列的索引

    index List Idx Predicate will get List with permutation and I want to know index of permutation For example index 4 1 3
  • Prolog 展平列表

    flatten A B R islist A gt flatten A R1 R R1 write A append A R1 R flatten B R1 flatten X X islist 这是我写的代码 但我有奇怪的问题 I get
  • Prolog家谱

    我做到了 但没有显示答案 当我询问兄弟姐妹 叔叔 阿姨时 这是我写的 有什么问题吗 uncle X Y male X sibling X Z parent Z Y uncle X Y male X spouse X W sibling W
  • 通过递归扩展 Prolog 目标?

    我 最终 实现了一些目标 这些目标将根据开始由 开始之后 and duration 然而 计划目标仅接受规定数量的任务 我想扩展计划目标的功能以接受单个列表并在计划时迭代该列表 不幸的是 我认为这将需要与can run and 冲突目标如下
  • 从终端查询不会打印任何内容

    当在命令行中运行时 这 swipl g write 42 t halt 打印 42 到STDOUT正如预期的那样 然而 这 swipl g X 42 t halt 不打印任何内容 它只是返回 我如何让它打印在 REPL 中打印的内容 即X
  • Prolog 中的隔离列表

    我很难理解如何让我的代码显示由偶数和奇数组成的隔离列表 我什至不确定我的理解缺乏什么 显然我对这门语言很陌生 必须在学校使用它 我的命令式和功能性思维不会让我知道这到底是怎么回事 哈哈 现在 不 我不是要求你做我的作业 我只是请你帮我看看我

随机推荐