微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Prolog中实现自动机

如何解决在Prolog中实现自动机

我是Prolog的新手。我设法相对较快地学习了C和Java,但是Prolog给我带来了很多麻烦。我的麻烦是了解列表和编写函数?例如。我们有这个自动机:

enter image description here

我可以用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将立即通过过渡2a在状态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 举报,一经查实,本站将立刻删除。