我用于解决 3 壶水谜题的序言程序有什么问题? [英] What's wrong with my prolog program for solving the 3 jugs of water puzzle?

查看:40
本文介绍了我用于解决 3 壶水谜题的序言程序有什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能找到为什么我在这段代码中的go"没有任何真正的答案?例如,我写了 go(7,3,l) 并且我认为它应该将 3 升水移到第二个水壶中,但根据序言它是错误的.怎么了?

Can anyone find why I can't have any true answers with my 'go' at this code? For example, I write go(7,3,l) and I suppose that it should move 3 litres of water to the second jug, but it is false according to prolog. What's wrong?

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

推荐答案

首先需要纠正它的基本语法:变量必须以大写开头,所以例如你必须改变这个规则

The first thing you need to correct it's basic syntax: variables must begin with uppercase, so for instance you must change this rule

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,l),move(D,C,r),state(D,C,D3,N,r)) :-
    D is D1-N,
    C is D2+N.

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

您应该意识到 N1 仅在第一个 newstate/2 过程中被赋值:然后更正该规则的其他实例.

You should realize that N1 is valorized just in the first newstate/2 procedure: then correct the other instances of that rule.

然后你应该删除无用的动态断言:想想你的实际断言/retractall用法:你需要的是改变状态在壶"之间移动水"的任何步骤:所以你应该在 go 中循环时断言/撤回 state/5,从初始状态(在启动程序时断言),到最终可接受的状态,在 go 中进行测试以停止循环.

Then you should remove the useless dynamic assertions: think about your actual assert/retractall usage: what you need is to change the state moving 'water' between 'jugs' at any step: so you should assert/retract state/5 while looping in go, from an initial state (assert this at start program), to a final acceptable state, to be tested in go to stop the cycle.

但是这种基于状态更改的风格导致非常难以调试.尝试完全移除动态、断言/撤回,并在循环中传递状态.

But this style based on state change leads to very difficult debugging. Try instead to remove altogheter the dynamic,assert/retractall, and pass around the state in your cycle.

这篇关于我用于解决 3 壶水谜题的序言程序有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆