Взаимная рекурсия Prolog

#recursion #prolog #mutual-recursion

#рекурсия #пролог #взаимная рекурсия

Вопрос:

Хорошо, я пишу некоторый код для проверки каждого значения путем взаимной рекурсии в Prolog. Пока это мой код:

 semestersok(SP) :-
    [Prior|Tail] = SP,
    sem1ok(SP).



%% sem1ok(SP) :- checks semester 1 of SP is ok
sem1ok(SP) :-
    [Sem1|Tail] = SP,
    sem2ok(Tail).

%% sem2ok(SP) :-
sem2ok(SP) :-
    [Sem2|Tail] = SP,
    sem1ok(Tail).
 

Я еще не ввел никакого кода для проверки (есть два отношения, поскольку он должен проверять переменные значения), у меня проблема с циклическим циклом кода, пока у него не появится пустой список, затем он завершается с ошибкой и возвращается с false (no). Поскольку этот код не манипулирует каким-либо кодом, я считаю, что он должен вернуться в том виде, в каком он есть сейчас. Почему это не так?

Ответ №1:

Вам нужны некоторые правила для пустого списка. Добавьте это:

 sem1ok([]).
sem2ok([]).
 

Кроме того, код может быть более интуитивно понятным, если вы напишете его следующим образом (поскольку различие между правилом, соответствующим пустому списку, и правилом, соответствующим непустому списку, более четкое):

 % Rules for sem1ok/1
sem1ok([]).
sem1ok([Sem1|Tail]):-
    ok(Sem1), % Something involving Sem1
    sem2ok(Tail).

% Rules for sem2ok/1
sem2ok([]).
sem2ok([Sem2|Tail]):-
    ok(Sem2), % Something involving Sem2
    sem1ok(Tail).
 

Комментарии:

1. Хорошо, извините, что звучит глупо, но где я могу это добавить? перед всем этим кодом?

2. Вы можете написать любое количество правил для предиката, и обычно все они упаковываются вместе. Итак, сгруппируйте правила для sem1ok/1 и sem2ok/1 отдельно.

3. Потрясающее спасибо, теперь оно работает 🙂 оно просто запрашивает действие после его выполнения, что странно, но оно возвращается истинным

4. Нет, подождите, я узнал, почему он это делает. Все хорошо, большое вам спасибо!