Nano Hash - криптовалюты, майнинг, программирование

ОШИБКА: вне глобального стека с append/3

У меня проблема. Я хочу реализовать предикат замены (E1, L1, E2, L2). Это верно, когда L1 и L2 являются одними и теми же списками, за исключением того, что в одном месте, где L1 имеет значение E1, L2 имеет E2. Кроме того, заменяется только одно вхождение и оно должно работать в любом режиме.

Например:

replace(2,[1,2,3,4],5,X) должно быть только решение X = [1,5,3,4].

replace(2,[1,2,3,2,1],5,X) следует вернуться к решениям X = [1,5,3,2,1] и X = [1,2,3,5,1].

replace(2,X,5,[1,5,3,5,1]) следует вернуться к решениям X = [1,2,3,5,1] и X = [1,5,3,2,1].

replace(X,[a,b,c,d],Y,[a,e,c,d]) должно быть только решение X = b, Y = e.

replace(X,[1,2,3,2,1],Y,[1,5,3,5,1]) не должно иметь решений (не должно быть).

Моя реализация:

 replace(E1, L1, E2, L2) :- 
    append(X, [E1|L_Tail], L1),
    append(X, [E2|L_Tail], L2).

Этот код в порядке. Однако, когда replace(2,X,5,[1,5,3,5,1]), он должен возвращать X = [1,2,3,5,1] и X = [1,5,3,2,1] и false. Он возвращает только первые 2 результата, а false не подошел. Программа заканчивается ERROR: Out of global stack.

24.09.2016

Ответы:


1

Этот вопрос был задан, и на него есть два ответа: тот, который вы использовали, и лучший< /а>. Тем не менее, я отвечу на вопрос «почему это решение не работает и как это исправить?».

Когда третий аргумент append/3 является переменной или неполным списком, это дает бесконечно много решений:

?- append(X, Y, [a|Z]).
X = [],
Y = [a|Z] ;
X = [a],
Y = Z ;
X = [a, _1860],
Z = [_1860|Y] ;
X = [a, _1860, _1872],
Z = [_1860, _1872|Y] ;
X = [a, _1860, _1872, _1884],
Z = [_1860, _1872, _1884|Y] . % and so on

Таким образом, когда первый список L1 является неполным списком, вызов append(X, [E1|Y], L1) будет продолжать "галлюцинировать" все более и более длинные списки. Второй вызов append/3 каждый раз будет завершаться ошибкой, Пролог сделает возврат, сделает еще более длинный список с первым append/3 и так далее. Вот почему вы попали в бесконечный цикл и в конечном итоге у вас закончится память (когда списки станут слишком длинными).

Один дешевый способ избежать этого - убедиться, что оба списка являются правильными списками одинаковой длины, прежде чем передавать их двум append. Например:

same_length([], []).
same_length([_|A], [_|B]) :- same_length(A, B).

Если вы используете SWI-Prolog, вы можете сделать это с помощью списка карт и лямбды yall:

maplist([_,_]>>true, L1, L2)

Пример запроса:

?- L2 = [1,5,3,5,1],
   maplist([_,_]>>true, L1, L2),
   append(X, [2|Y], L1),
   append(X, [5|Y], L2).
L2 = [1, 5, 3, 5, 1],
L1 = [1, 2, 3, 5, 1],
X = [1],
Y = [3, 5, 1] ;
L2 = [1, 5, 3, 5, 1],
L1 = [1, 5, 3, 2, 1],
X = [1, 5, 3],
Y = [1] ;
false.
24.09.2016
  • Привет Борис, работает. Ваш ответ ясен и хорошо структурирован. Спасибо большое! 24.09.2016
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..