我试图递归构建一个状态列表,其中包括具有某种条件的状态。我正在尝试使用有条件的方式来做到这一点,但是该列表不是通过递归电话积累的。
%Base case
epsilon_closure_helper(State, [], States) :-
States = [State].
%Recursive Case
epsilon_closure_helper(State, Transitions, States) :-
Transitions = [Head|Tail],
epsilon_closure_helper(State, Tail, States1),
Head = next(A, B, Symbol),
%If test_state true: append State B to States list else append empty list
test_state(State, A, Symbol) -> append(States1, [B], States) ;
append(States1, [], States).
test_state(TargetState, State, Symbol) :-
State = TargetState,
Symbol = epsilon.
%Example list of Transitions (next). Transitions contain a From state, a To
state and Symbol
[next(state(0, not_accepting), state(1, not_accepting), epsilon),
next(state(1, not_accepting), state(3, not_accepting), epsilon)]
即使我将其他条件更改为状态=状态1也行不通。我想要的是状态变量具有具有一定条件的所有状态术语。有什么建议,我该怎么办或我出错了哪里?任何帮助将非常感激!!:)
编辑:逻辑如下。如果从过渡列表中的过渡中的状态a匹配epsilon_closure_helper谓词状态变量中提供的目标,并且过渡符号为epsilon,我想将状态b从同一过渡添加到状态列表。过渡表示为:下一步(fromstate,tostate,符号)状态表示为:状态(数字,接受)对此解决方案的接受变量无关紧要。
由于您没有给出任何示例输入和输出,并且缺少某些条款/事实,例如test_state/3
这是一个可比的解决方案。
使用螺纹变量(即State
)时,将其习惯的方法放在参数的末尾:
epsilon_closure_list([H|T],State0,State)
接下来,使用螺纹变量,输入变量已将0
附加到其上,并且结果变量没有附加数字。其余变量附加了一个增加的数字。
在您的代码中,尾巴是在每个项目之前处理的,这很好,但是当递归调用在该条款的末尾时,它被称为尾部回归。当使用尾部回收时,许多编译器可以优化代码。此答案使用尾部回程。
您的代码还使用=/2
,可以纳入来简化代码,但是在学习或编写一些新代码时,我经常使用它,直到我使用代码为止。此答案将使所有=/2
分解出来。
可能会纳入append/3
的使用,在大多数情况下可以使用,但是由于您没有给出足够的示例代码,因此该答案在答案中留下了append/3
。
完成代码
epsilon_closure_list([H|T],State0,State) :-
(
valid(H)
->
append(State0,[H],State1)
;
append(State0,[],State1)
),
epsilon_closure_list(T,State1,State).
epsilon_closure_list([],State,State).
valid(a).
valid(c).
valid(d).
测试用例
:- begin_tests(epsilon_closure).
epsilon_closure_test_case([],[]).
epsilon_closure_test_case([b],[]).
epsilon_closure_test_case([b,e],[]).
epsilon_closure_test_case([a],[a]).
epsilon_closure_test_case([a,b],[a]).
epsilon_closure_test_case([a,b,c],[a,c]).
test(1,[forall(epsilon_closure_test_case(Input,Expected_result))]) :-
epsilon_closure_list(Input,[],State),
assertion(State == Expected_result ).
:- end_tests(epsilon_closure).
示例运行
?- run_tests.
% PL-Unit: epsilon_closure ...... done
% All 6 tests passed
true.