如何解决在Prolog中实现自动机
我是Prolog的新手。我设法相对较快地学习了C和Java,但是Prolog给我带来了很多麻烦。我的麻烦是了解列表和编写函数?例如。我们有这个自动机:
我可以用C和Java来完成此任务,没有问题。但是当然要Prolog。以我目前的知识,我可以做这样的事情:
div.card-body
请您知道我的知识在哪里。很基本。我确实阅读了立即学习Prolog中的列表一章,但仍然让我感到困惑。他们给了我们一个提示:
每个节点都应显示为:
% 1. Check whether all integers of the list are < 10.
less_than_10([]).
less_than_10([Head|Tail]) :-
Head < 10,less_than_10(Tail).
他们还告诉我们将有问题的列表传递给谓词,如果该列表适合自动机,则返回 delta(1,d,2)
% or
alpha(2,a,2)
,如果满足条件,则返回 true
不是:
false
输出为 accept([d,b,c,c]).
。
从这里去哪里?我猜测第一步是检查列表的 true
是否为 Head
。我怎么做?另外,我是否应该将每个节点作为事实添加到知识库中?
解决方法
这很容易。超级直接,远远超过使用C或Java的情况。
让我们为此图编写一个解释器:
- 给出了命名转换的列表;
- 使用给定的图形沿着穿过该图形的路径进行过渡;
- 如果我们进入最终状态,则接受(成功)列表;
- 如果不这样做,则拒绝(失败)列表;
- 然后..如果列表不能由给定的图形生成,则抛出异常。
Prolog为我们提供了不确定性,以防万一。很好。
我们没有一个描述自动机的类。从某种意义上说,Prolog程序是自动机。我们只有一组谓词,它们通过归纳定义来描述自动机。实际上,如果您在下面的源代码周围加上模块定义,那么您确实拥有该对象。
首先描述该图。这只是一组Prolog事实。
根据需要,我们给出节点(以整数标记)之间的过渡(以原子标记),并指明哪些是起始节点和结束节点。无需列出节点或边本身。
delta(1,d,2).
delta(2,a,b,4).
delta(2,e,5).
delta(2,c,3).
delta(3,6).
delta(6,5).
start(1).
end(4).
end(5).
一个简单的数据库。当然,这只是一种可能的表示。
现在是图助步器。我们可以在此处使用Definite Clause Grammars,因为我们正在处理一个列表,但不要这样做。
首先,谓词“接受”或“拒绝”转换列表。
它看起来像:
% accepts(+Transitions)
它以开始状态开始,然后通过从列表中移除过渡直到列表为空来“行走”。然后,它检查它是否处于结束状态。
accepts(Ts) :- % accept the list of transitions if...
start(S),% you can accept the list starting
accepts_from(S,Ts). % from a start state
accepts_from(S,[T|Ts]) :- % accepts the transitions when at S if...
delta(S,T,NextS),% there is a transition S->NextS via T
accepts_from(NextS,Ts). % and you can accept the remaining Ts from NextS. (inductive definition)
accepts_from(S,[]) :- % if there is no transition left,we accept if...
end(S). % we are a final state
啊,我们想抛出该图不可能的路径。进行一些修改:
accepts(Ts) :- % accept the list of transitions if...
start(S),Ts). % and you can accept the remaining Ts from NextS.
accepts_from(S,[T|Ts]) :- % accepts the transitions when at S if...
\+ delta(S,% there is NO transition S->NextS via T
format(string(Txt),"No transition at ~q to reach ~q",[S,[T|Ts]]),throw(Txt).
accepts_from(S,we accept if...
end(S). % we are a final state
等等:
?- accepts([d,c]).
true ; % yup,accepts but maybe there are other paths?
false. % nope
?- accepts([d,e]).
true ;
false.
?- accepts([d,a]).
false.
?- accepts([d,a]).
ERROR: Unhandled exception: "No transition at 3 to reach [e,a]"
上面的代码还应该能够找到通过图形的可接受路径。但事实并非如此:
?- accepts(T).
... infinite loop
这不好。
这样做的主要原因是accept/2
将立即通过过渡2
和a
在状态b
生成无限路径循环。因此,需要添加一个“深度限制器”(关键字为“迭代加深”)。
第二个原因是,例如测试\+ delta(S,NextS)
将在节点4
上成功(因为该节点无处可去)并导致异常,然后再尝试无处可去(最后一条)。因此,在生成时,投掷是一个障碍,人们只想拒绝。
附录:同时生成
以下内容仅接受/拒绝,不抛出,但也可以生成。
:- use_module(library(clpfd)).
accepts(Ts,L) :- % Accept the list of transitions Ts of length L if
start(S),% ...starting from a start state S
accepts_from(S,Ts,L). % ...you can accept the Ts of length L.
accepts_from(S,[T|Ts],L) :- % Accept the transitions [T|Ts] when at S if
(nonvar(L)
-> L >= 1
; true),% L (if it is bound) is at least 1 (this can be replaced by L #> 0)
delta(S,SN),% ...and there is a transition S->SN via T
Lm #= L-1,% ...and the new length is **constrained to be** 1 less than the previous length
accepts_from(SN,Lm). % ...and you can accept the remaining Ts of length Lm from SN.
accepts_from(S,[],0) :- % If there is no transition left,length L must be 0 and we accept if
end(S). % ...we are a final state.
delta(1,5).
start(1).
end(4).
end(5).
generate :-
between(0,7,L),findall(Ts,accepts(Ts,Bag),length(Bag,BagLength),format("Found ~d paths of length ~d through the graph\n",[BagLength,L]),maplist({L}/[Ts]>>format("~d : ~q\n",[L,Ts]),Bag).
等等:
?- accepts([d,c],_).
true ;
false.
?- accepts([d,a],_).
false.
?- accepts([d,_).
false.
?- generate.
Found 0 paths of length 0 through the graph
true ;
Found 0 paths of length 1 through the graph
true ;
Found 2 paths of length 2 through the graph
2 : [d,d]
2 : [d,e]
true ;
Found 4 paths of length 3 through the graph
3 : [d,d]
3 : [d,e]
3 : [d,e]
true ;
Found 9 paths of length 4 through the graph
4 : [d,d]
4 : [d,e]
4 : [d,c]
true
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。