Prolog-仅包含某些术语的术语构建术语清单



我试图递归构建一个状态列表,其中包括具有某种条件的状态。我正在尝试使用有条件的方式来做到这一点,但是该列表不是通过递归电话积累的。

%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.