【问题标题】:How to find useless states in a finite state machine Prolog如何在有限状态机 Prolog 中找到无用的状态
【发布时间】:2014-11-24 01:16:57
【问题描述】:

我一直在考虑一种解决方案来查找在特定自动机中定义的所有无用状态,并且我知道一种方法是从开始状态开始移动,然后请求以下状态,所有这些都存储在 Prolog 谓词中数据库。我没有很好地编写代码,因为我正在学习 Prolog。我希望有人能帮我解决这个问题。我在这里留下我所拥有的。

有限状态机结构。 fa_start -> 初始状态,fa_move -> 从一个状态到另一个状态的有效移动,fa_final -> 最终状态。

% Start State
:- assert(fa_start(fa_1, s_0)).
% Final States 
:- assert(fa_final(fa_1, s_5)).

:- assert(fa_move(fa_1, s_0, s_1, a)).
:- assert(fa_move(fa_1, s_1, s_4, b)).
:- assert(fa_move(fa_1, s_0, s_2, c)).
:- assert(fa_move(fa_1, s_2, s_4, d)).
:- assert(fa_move(fa_1, s_2, s_5, e)).
:- assert(fa_move(fa_1, s_0, s_3, f)).
:- assert(fa_move(fa_1, s_3, s_5, g)).
:- assert(fa_move(fa_1, s_6, s_3, h)).
:- assert(fa_move(fa_1, s_6, s_7, i)).
:- assert(fa_move(fa_1, s_7, s_8, j)).

现在,这是我一直在编写的代码。这个想法是从fa_start 开始,然后使用有效的fa_move 继续移动,直到它无法到达fa_final

adjacent(fa, N, M):-
   fa_move(fa, N, M, _).

adjacent_recursive(fa, N, L):-
   fa_start(fa, N),
   findall(l,adjacent(fa,N,_),L).

find_paths(fa):-
   adjacent_recursive(fa,s_0,_).

提前感谢您的所有帮助。

【问题讨论】:

  • 您的具体问题是什么?请注意,findall(l,adjacent(fa,N,_),L) 可能存在语法错误。 l 是一个原子。此外,您对fa_movefa_start 的查询均引用fa,但您的事实使用fa_1。所以他们永远不会匹配。
  • 你好。谢谢你的笔记。我想要的是打印所有无用的状态。
  • 而且,我已经阅读了link 中的算法,但我不知道如何适应它。

标签: prolog finite-automata state-machine


【解决方案1】:

我知道很难找到与我的具体问题相关的准确信息。我一直在努力,终于找到了解决方案,可能不是最好的,但可以达成交易。我把这个想法归功于this site。如果您发现错误,我们将不胜感激。

现在,在给定如上实现的有限状态自动机的情况下,以下代码打印无用状态。

find_useless_states(FA):- retractall(utiles(_)),retractall(visited(_)),
        forall(fa_final(FA,S),assert(utiles(S))),
        find_useless_states2(FA).
find_useless_states2(FA):- retract(utiles(S)),
     not(visited(S)), assert(visited(S)),
     forall((fa_move(FA,Y,S,_), not(visited(Y))),(asserta(utiles(Y)))),
     find_useless_states2(FA).
find_useless_states2(_).

difference(L1, L2, R) :- intersection(L1, L2, I),
                     append(L1, L2, All),
                     subtract(All, I, R).

find_all_states_as_list(FA,L):- findall(X,fa_move(FA,X,_,_),M),findall(Y,fa_move(FA,_,Y,_),N),merge(M,N,LL),sort(LL,L).
find_useful_states_as_list(L):- findall(X,visited(X),L).

print_useless_states(FA):- find_all_states_as_list(FA,L),find_useful_states_as_list(M), difference(L,M,R), length(R,D),write(R),nl,write(D).

希望它可以帮助其他人。一些代码想法已从 stackoverflow 中发布的问题中使用。我感谢回答这些问题的人。

【讨论】:

    【解决方案2】:

    可以将动态数据库用于所有这些事情,但它很容易变得非常难以维护。我宁愿用你的定义编译文件,从而避免手动执行assertz/1

    uselessstate(Aut, Usl) :-
       setof(S0, S^( closure0(adjacent(Aut), S0,S), fa_final(Aut,S) ), S0s),
       setof(t, A^B^( adjacent(Aut, A,B), (Usl=A;Usl=B) ), _),
       non_member(Usl, S0s).
    
    unreachable(Aut, Usl) :-
       setof(S, S0^( fa_start(Aut, S0), closure0(adjacent(Aut), S0,S) ), Ss),
       setof(t, A^B^( adjacent(Aut, A,B), (Usl=A;Usl=B) ), _),
       non_member(Usl, Ss).
    

    definition of closure0/3non_member/2 在另一个答案中找到。

    【讨论】:

    • 也感谢您的回答。无用状态与不可访问状态不同,但我正在研究一种解决方案来寻求不可访问状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多