Prolog 初级序言问题

Prolog 初级序言问题,prolog,Prolog,我们有一个盒子,里面有红色和黄色的球。 一个男人每天都会从禁区里拿两个球,如果他拿不到两个球,比赛就结束了。 盒子旁边有一堆红球。 如果该男子从禁区中取出的两个球相似,他会将红球放入禁区, 如果他们不一样,他会把黄色的球放进盒子里。 我们假设长方体是这样表示的 initialCan([y, r, y, r, y, r, y, r, y, r]). y代表黄色的球,r代表红色的球。 该男子从列表开始处取出2个球, 然后他又把1个球放回了名单的开头。 那么,在Prolog中,给出框中最后一个球的颜

我们有一个盒子,里面有红色和黄色的球。 一个男人每天都会从禁区里拿两个球,如果他拿不到两个球,比赛就结束了。 盒子旁边有一堆红球。 如果该男子从禁区中取出的两个球相似,他会将红球放入禁区, 如果他们不一样,他会把黄色的球放进盒子里。 我们假设长方体是这样表示的

initialCan([y, r, y, r, y, r, y, r, y, r]).
y代表黄色的球,r代表红色的球。 该男子从列表开始处取出2个球, 然后他又把1个球放回了名单的开头。 那么,在Prolog中,给出框中最后一个球的颜色的过程是什么呢
框开始时是否包含?

您可以将问题抽象为在可能状态空间中进行搜索

search(FinalState, FinalState):-
    is_final(FinalState).

search(CurrentState, FinalState):-
    transition(CurrentState, NextState),
    search(NextState, FinalState).

solution(FinalState):-
    initial_state(State0),
    search(State0, FinalState).
所以你从一个州跳到另一个州,直到最后一个州成为你的解决方案。你需要做一些事情:

  • 为一个状态设计一个表示(例如,一个状态可能是一个类似于
    [r,y,r,…]
    的列表)

  • 编写一个谓词
    initial_state(S0)
    ,如果
    S0
    是游戏的初始状态,则满足该谓词

  • 编写一个谓词
    transition(S1,S2)
    ,如果可以从
    S1
    S2

  • 编写一个谓词
    是final(S)
    ,如果
    S
    是final状态,则该谓词为true


  • 将状态设计为
    框(黄色计数、红色计数)
    甚至更容易,而且不必麻烦任何特定列表(毕竟,球都是相同的,就像电子一样)。这是我的尝试。我可能在这里写别人的作业,但这确实很有趣

    也考虑Edsger W. Dijkstra的检查,其中描述了这个问题。

    % last_ball(box(Yellow_initial_count, Red_initial_count), Last_ball_color, Time_at_end)
    
    
    % ---------- TRIVIAL CASES ---------
    
    % if there is only 1 yellow ball, the color is 'yellow' and we needed zero steps to reach this state
    
    last_ball(box(1,0), yellow, 0).
    
    % if there is only 1 red ball, the color is 'red' and we needed zero steps to reach this state
    
    last_ball(box(0,1), red,    0).
    
    % ---------- CASES DEFINING INDUCTION OVER Yellow+Red BALLS -----------
    
    % take two yellow: check that this is possible for the given box, 
    % then find out what the last color is from the reduced counts, then define the number of steps to be higher by 1
    
    last_ball(box(YI, RI), LBC, TAE) :- YI>=2, YIp is (YI-2), RIp is (RI+1), last_ball(box(YIp,RIp),LBC,TAEp), TAE is (TAEp+1).
    
    % take two red: check that this is possible for the given box, 
    % then find out what the last color is from the reduced counts, then define the number of steps to be higher by 1
    
    last_ball(box(YI, RI), LBC, TAE) :- RI>=2, YIp is YI, RIp is (RI-2+1), last_ball(box(YIp,RIp),LBC,TAEp), TAE is (TAEp+1).
    
    % take a red and a yellow: check that this is possible for the given box, 
    % then find out what the last color is from the reduced counts, then define the number of steps to be higher by 1
    
    last_ball(box(YI, RI), LBC, TAE) :- RI>=1, YI>=1, YIp is (YI-1+1), RIp is (RI-1), last_ball(box(YIp,RIp),LBC,TAEp), TAE is (TAEp+1).
    
    % Now ask for example:
    % ?- last_ball(box(2,1), C, T).
    
    % ===================================
    % This problem is of course Edsger W. Dijkstra's "balls in the urn" problem, and 
    % there is a very easy way to deduce the color without exhautsive check of the move tree, as Prolog does in the above.
    % See: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD07xx/EWD720.html
    
    last_ball_ewd(box(YI, _), red)    :- 0 is (YI mod 2).
    last_ball_ewd(box(YI, _), yellow) :- 1 is (YI mod 2).
    
    % We can test this by trying to find a counterexample of the result of last_ball_ewsd for the other color via '\+'
    
    othercolor(red,yellow).
    othercolor(yellow,red).
    
    verify(box(YI, RI)) :- last_ball_ewd(box(YI, RI), LBC), othercolor(LBC,LBCO), \+last_ball(box(YI, RI), LBCO, _).
    
    % Now ask for example:
    % ?- verify(box(2, 1))
    

    在Prolog中,列表可以表示为
    [H | T]
    ,其中
    H
    是第一个元素,
    T
    是列表的其余部分(
    T
    本身就是一个列表)。因此,如果您查询,
    initialCan([H | T])
    ,在您的示例中,
    H
    将被实例化为
    y
    H=y
    将为true)。你有没有听过Prolog教程,或者你在上课?我正在上课,我读了一些教程,我理解了主要概念和它的工作原理,但我没有找到一个参考教程,它教你解决类似的简单问题。我要么找到教复杂问题的教程,要么找到只教主要概念的教程。我需要一些中间的东西,你不想考虑程序,而是统一和谓词。列表是Prolog中的常见结构。一个好的教程应该提供大量使用列表的示例。当您输入时,
    initialCan(L)
    ,这将统一
    L
    [y,r,y,r,y,r,y,r]
    (这样
    L
    将与列表一起实例化)。然后您可以将
    L
    [H | T]
    形式统一起来,并说,
    L=[H | T]
    。当这些表达式统一后,Prolog通过实例化
    H
    T
    中第一个元素的值,以及表示
    L
    其余元素的列表来实现这一点。我将尝试调整您的指导谢谢,我认为这是我需要的想法非常感谢亲爱的@David为您所做的努力。我非常感谢您的好意:)我想更多地了解Prolog及其解决问题的概念和方法。我对这种解决问题的新方法有点困惑。我会越来越多地练习。我希望我会越来越好。坚持不懈是前进的道路。这可能会有所帮助:“Prolog程序”是关于指定输入项(如
    box(1,0)
    )和输出项(如
    yellow
    )之间的关系的,通常以递归的方式加入附加约束。内置的深度优先回溯功能实际上很糟糕。也许从数据日志开始会对真正的初学者有所帮助。