Prolog-以递归方式建立术语列表,仅包括某些术语

时间:2019-03-05 07:09:44

标签: 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)]

即使我将else条件更改为States = States1,它也不起作用。我想要的只是州变量,使所有具有特定条件的州条款都具有。有什么建议可以解决我的问题?任何帮助将非常感激!! :)

编辑:因此逻辑如下。如果转换列表中转换的状态A与epsilon_closure_helper谓词的State变量中提供的目标匹配,且转换符号为epsilon,我想将同一转换中的状态B添加到状态列表中。 过渡表示为:next(FromState,ToState,Symbol) 状态表示为:状态(编号,接受) 接受变量对此解决方案无关紧要。

1 个答案:

答案 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