Бесконечный цикл, вызванный Append?

У меня есть небольшой вопрос относительно почему мой код зависает при запуске. Код предназначен для проекта, который у меня есть в классе, но мы провели один урок, изучая Пролог, поэтому многое из того, что я узнал, я искал и выучил сам. Я приношу свои извинения, если мой код содержит ужасные стилистические ошибки, но опять же, поскольку мы так и не узнали формально, как нам «следует» использовать Пролог, это основано главным образом на моих собственных экспериментах.

Цель сегмента кода, который я пишу, состоит в том, чтобы более или менее сформировать цепочку, которая соединяет одного актера с другим через серию фильмов, в которых они были.

У меня есть функция, которую я вызываю, предназначенная для создания связей между начальным актером, всеми возможными связанными актерами, конечным актером и списком фильмов, которые их соединяют. Вероятно, это ужасно неэффективный метод, однако такая реализация решает две части задания с помощью одного сегмента кода.

Код, вызывающий функцию, работает, и для упрощения чтения я буду опускать его, пока не попросят поделиться им. Короче говоря, он утверждает globalStartingActor и передает два пустых списка (ActorList = [] и MovieList = []) функции doActorAssertions.

В свою очередь, у нас есть doActorAssertions. Это его переработанная версия, которая должна быть упрощена и легче читать, но в ней отсутствуют массовые комментарии, которые были раньше.

doActorAssertions(ActorsName,ActorList,MovieList) :-
    isNotInList(ActorsName,ActorList) ->
    (
        findMoviesIn(ActorsName,MoviesIn),%finds all movies ActorsName is in
        howLong(MoviesIn,LenMoviesIn),%Sees how many movies there are.
        (
            LenMoviesIn ==0;
            (
                append(ActorsName,ActorList,UpdatedActorList),%this causes errors!
                globalStartingActor(GSAName),%asserted starting actor
                assert(connectedActors(GSAName,ActorsName,MovieList)), %says that the GSAName is connected to ActorsName by a list of movies MovieList.
                write(actorAsserted),               
                addAndTraverse(MoviesIn,UpdatedActorList,MovieList) %Goes to propegate all movies the actor is in, then actors in those movies, then recursively calls this function again.     
            )
        )
    ),
    true.

Как я уже говорил ранее, тег append, похоже, был источником ошибки! Это действительно так, когда я упрощаю код до того, что указано выше. Я просто комментирую, что добавляется, и тело кода работает.

Почему же тогда добавление препятствует правильной работе кода? Мне нужно добавить (или аналогичную функцию) в эту часть кода!


person Chaosfissure    schedule 03.11.2012    source источник


Ответы (1)


Является ли ActorsName списком? Название переменной предполагает, что это так, а также использование в append/3, но тогда что означает isNotInList(ActorsName,ActorList)? Частичная или полная дизъюнкция? Это может быть причиной бесконечного цикла, возможно, вам следует использовать разницу этих наборов для увеличения ActorList.

Вы должны стараться избегать assert/1 и вместо этого передавать состояние в переменных. См. этот другой ответ для схемы, делающей что-то очень похожее на то, что вы пытаетесь сделать здесь.

Это бесполезно, может опечатка, но тогда я не понимаю ->

  ...
  ),
  true.

думаю стоит прочитать

  ...
  );     % note the semicolon!
  true.
person CapelliC    schedule 03.11.2012
comment
Фу. Комментарии можно редактировать только пять минут, что это за темная магия? ActorsName в основном то же самое, что и имя актера — это строка в единственном числе, а не список. isNotInList в основном является отрицанием 'memberof/member', который принимает один элемент и список в качестве параметров. Точка с запятой в конце - я не понимаю, почему я не поставил ее там изначально. Хороший улов, спасибо! Да, я полагал, что утверждения не будут самым красивым способом ведения дел. Я также посмотрю на ссылку, которой вы поделились. - person Chaosfissure; 03.11.2012
comment
Хорошо, поэтому я снова взглянул на добавление - как вы упомянули, что ActorsName предполагает, что это должен быть список. Я изменил добавление на добавление([ActorsName],ActorList,UpdatedActorList), и, похоже, это устранило ошибку. Спасибо, что указали на это; Я полагал, что мне может сойти с рук добавление элементов, не входящих в список, к списку, как я делаю все время в большинстве языков программирования! - person Chaosfissure; 03.11.2012