我知道我需要弄清自己的功课,但是看到班上没有人能弄明白,我需要一些帮助。序言:认识到一个^ n b ^(n + 1)语言n> = 1
写Prolog程序,使得
p(X)
为真,如果X
是由n
a
的后面n+1
b
的名单,对于任何n >= 1
。
我知道我需要弄清自己的功课,但是看到班上没有人能弄明白,我需要一些帮助。序言:认识到一个^ n b ^(n + 1)语言n> = 1
写Prolog程序,使得
p(X)
为真,如果X
是由n
a
的后面n+1
b
的名单,对于任何n >= 1
。
您应该使用计数器来跟踪您迄今为止发现的内容。当您找到b
时,请在计数器中添加一个。当你找到一个a
时,减去一个。您的计数器在整个列表遍历后的最终值应为1,因为您希望b
的数量比a
的数量多1。这里有一个如何编写代码的例子:
% When we see an "a" at the head of a list, we decrement the counter.
validList([a|Tail], Counter) :-
NewCounter is Counter - 1,
validList(Tail, NewCounter).
% When we see an "b" at the head of a list, we increment the counter.
validList([b|Tail], Counter) :-
NewCounter is Counter + 1,
validList(Tail, NewCounter).
% When we have been through the whole list, the counter should be 1.
validList([], 1).
% Shortcut for calling the function with a single parameter.
p(X) :-
validList(X, 0).
现在,这个会做几乎你想要的东西 - 它匹配所有n >= 0
规则,当你想为所有n >= 1
。在典型的家庭作业答案中,我留下了最后一点让你自己补充。
谢谢,作业已经到期,我只想知道该怎么做。我的课程是关于编程语言原理的,因此我们正在接受像Prolog和Ada这样的教学,但没有被教授语言,所以我们需要学习。所以谢谢! – poorStudent
我不记得如何在Prolog的这一点,但这个想法是这样的:
规则1: 如果LISTSIZE是1,如果该元素是B.
第2条返回true : 如果列表大小为2,则返回false。
规则3: 检查列表中的第一项是A,最后一个是B. 如果这是真的,返回元素2 LISTSIZE-1解决方案。
如果我正确理解您的问题,那应该是完美的Prolog样式解决方案。
编辑:我完全忘了这件事。我编辑了答案,考虑了n = 1和n = 2的情况。感谢Heath Hunnicutt。
这是一个很好的答案。它留下了一些情况,如列表少于2个字符长。为0和1项目列表添加条款将使这个答案成为“完美的Prolog式解决方案。“ –
是的,我忘了添加这些规则,谢谢你告诉我,我将在以后的帖子中编辑它(现在必须离开) – George
问题在于检查链表的最后一项是O(n )操作,这很慢并且没有自然的语法,它更符合逻辑声明式的风格,但不幸的是,在这种特殊情况下,这不是Prolog所鼓励的。 –
这里是我的深奥的解决方案
:-use_module(library(clpfd)).
n(L, N) -->
[L],
{N1 #= N-1
},
!, n(L, N1).
n(_, 0) --> [], !.
ab -->
n(a, N),
{N1 is N + 1
},
n(b, N1).
p(X) :- phrase(ab, X).
test :-
p([b]),
p([a,b,b]),
p([a,a,b,b,b]),
p([a,a,a,b,b,b,b]),
\+ p([a]),
\+ p([a,b]),
\+ p([a,a,b,b]),
\+ p([a,b,b,c]).
测试:
?- [ab].
% ab compiled 0.00 sec, -36 bytes
true.
?- test.
true.
请教老师。如果真的没有人理解它,问题在于教学,你需要和老师一起提出。 – GManNickG
@ Neil Butterwork:我记得,'!'是我认为可以防止回溯的切割符号。不记得发生了什么,如果你把它们放在一起。 – FrustratedWithFormsDesigner
问题是您的目标语言还是执行此操作所需的逻辑?但是,格曼是正确的。假设你为这种教育付款,你应该首先与教授或TA联系。 – avirtuos