我试图递归地建立状态列表,只包括具有某种条件的状态。我正在尝试使用条件语句来执行此操作,但是该列表不是通过递归调用来累积的。
%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)]
即使我将else条件更改为States = States1,它也不起作用。我想要的只是州变量,使所有具有特定条件的州条款都具有。有什么建议可以解决我的问题?任何帮助将非常感激!! :)
编辑:因此逻辑如下。如果转换列表中转换的状态A与epsilon_closure_helper谓词的State变量中提供的目标匹配,且转换符号为epsilon,我想将同一转换中的状态B添加到状态列表中。 过渡表示为:next(FromState,ToState,Symbol) 状态表示为:状态(编号,接受) 接受变量对此解决方案无关紧要。
答案 0 :(得分:1)
由于您未提供任何示例输入和输出,并且缺少某些子句/事实,例如test_state/3
这是一个可比的解决方案。
在使用线程变量(即State
)时,通常的做法是将它们放在参数的末尾:
epsilon_closure_list([H|T],State0,State)
接下来,在带有线程变量的情况下,输入变量后面附加0
,结果变量后面没有数字。其余变量的末尾附加一个递增的数字。
在您的代码中,尾部在每个项目之前进行处理,这很好,但是当递归调用位于子句的末尾时,它称为tail-recursion。使用尾递归时,许多编译器可以优化代码。此答案使用尾递归。
您的代码还使用=/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.
示例运行
Microsoft.Common.CurrentVersion.Targets