我试图通过阅读Ulle Endriss的讲义来了解Prolog编程.当我对练习的解决方案没有达到预期的效果时,我发现很难给出一个很好的解释.我认为这与我对Prolog评估表达式的方式的不稳定理解有关.
第20页的练习2.6调用谓词的递归实现,该谓词的last1行为类似于内置谓词last.我的尝试如下:
Run Code Online (Sandbox Code Playgroud)last1([_ | Rest], Last) :- last1(Rest, Last). last1([Last], Last).
它给出了正确的答案,但对于具有多个元素的列表,我必须键入分号才能终止查询.这last1与内置的不同last.
?- last1([1], Last).
Last = 1.
?- last1([1, 2], Last).
Last = 2 ;
false.
Run Code Online (Sandbox Code Playgroud)
如果我切换我声明规则和事实的顺序,那么我需要在两种情况下键入分号.
我想我知道为什么Prolog认为last1可能还有一个解决方案(因此是分号).我想它遵循评估顺序
last1([1, 2], Last).
==> last1([2], Last).
==> last1([], Last). OR Last = 2.
==> false OR Last = 2.
Run Code Online (Sandbox Code Playgroud)
这似乎表明我应该寻找一种方法来避免匹配Rest带[].无论如何,我没有解释为什么切换声明的顺序应该有任何影响.
问题1: 对行为的正确解释是last1什么?
问题2: 如何实现last1与内置无法区分的谓词last?
我正在研究玩具问题,以帮助我理解Mathematica中模式匹配的想法.以下代码的行为与我的预期不符,我无法弄清楚我对PatternTest的理解有什么问题.
MatchQ[{2, 1, 2, 5}, {x__?(FromDigits[{#}] > 3 &), y__}]
Run Code Online (Sandbox Code Playgroud)
我期望这段代码检查列表是否{2,1,2,5}可以写成两个连续(非空)序列,这样我们从第一个序列得到的整数大于3.因为{Sequence[2,1],Sequence[2,5]}是重写列表的一种方法FromDigits[{2,1}] > 3,我希望该代码返回值True.但事实并非如此.
我对代码的解释有什么问题?
第二版" 如何设计程序"中的练习42 解释了DrRacket突出显示了cond下面代码中的最后两个子句,因为测试用例并未涵盖所有可能的情况.
; TrafficLight -> TrafficLight
; given state s, determine the next state of the traffic light
(check-expect (traffic-light-next "red") "green")
(define (traffic-light-next s)
(cond
[(string=? "red" s) "green"]
[(string=? "green" s) "yellow"]
[(string=? "yellow" s) "red"]))
Run Code Online (Sandbox Code Playgroud)
我的理解是else最后的一个条款应该涵盖其余的案例,所以我尝试替换最后的表达式:
(define (traffic-light-next s)
(cond
[(string=? "red" s) "green"]
[(string=? "green" s) "yellow"]
[(string=? "yellow" s) "red"]
[else "green"]))
Run Code Online (Sandbox Code Playgroud)
这并不能解决突出问题.这里发生了什么?