Пролог - вставка с фактами - PullRequest
0 голосов
/ 05 января 2012

Мне нужно запрограммировать предикат в прологе, который вставляет элемент в указанную позицию и, следовательно, изменяет номер позиции остальных элементов в списке. Я достиг следующего фрагмента кода, который реализует предикат, который вставляет элемент в конец списка. В секторе баз данных, кроме LIST, у нас также есть LONG, который указывает количество элементов в списке. В конце я попытаюсь реализовать некоторый код для предиката de. Кто-нибудь может сказать мне, что там не так? Я здесь потерян.

Domains
name=symbol
position=integer
element=integer
Database
    list(name,position,element)
    long(name,integer)

Predicates
     nondeterm inserirf(element)

Clauses
    list(b,1,1). 
    list(b,2,5). 
    list(b,3,8). 
    list(b,4,3). 
    long(b,4).
    inserirf(V):-
        long(b,X),
        Y=X+1,
        assertz(list(b,Y,V)),
        assertz(long(b,Y)),
        retract(long(b,X)),
        long(b,Q),
        list(b,Q,P),
        write(P),nl.

Goal
    inserirf(7).

Моя последняя попытка:

Predicates
 nondeterm inserirl(nom,pos,element)

Clauses
    list(b,1,1). 
    list(b,2,5). 
    list(b,3,8). 
    list(b,4,3).
    list(b,5,10).
    list(b,6,11). 
    long(b,6).

  inserirl(L,Pos,E):-
  long(L,Long),
  Pos > Long,
  NouLong = Long+1,
  retract( long(L,Long) ),
  assertz( list(L,Pos,NouLong) ),
  assertz( long(L,NouLong) ).


inserirl(L,Pos,E):-
    long(L,X),
    XaPassar=X-1,
    retract(llista(L,Pos,E)),
    retract( long(L,X) ),
    assertz( long(L,XaPassar) ),

    inserirl(L, XaPassar,E),
    long(L,Y),
    Y2=Y+1,
    retract( long(L,Y) ),
    assertz( long(L,Y2) ),
    assertz(llista(L,Pos,E)).

Goal
    inserirl(b,3,9).
% 3 -> position
% 9 -> element
% b -> name of list

Сотни благодаря любой помощи.

Ответы [ 3 ]

0 голосов
/ 09 января 2012

Вот базовый случай:

inserirl(L,Pos,E):-
  long(L,Len),
  Pos > Len,
  NewLen is Len+1,
  retract( long(L,Len) ),
  assertz( list(L,Pos,NewLen) ),
  assertz( long(L,NewLen) ).

Для рекурсивного случая измените факты, чтобы сделать список 1 короче, вставьте новый элемент в ТО, а затем верните обратно элемент, удаленный в конец.

0 голосов
/ 09 января 2012

Относительно "моей последней попытки":

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

Примечание. В конечном итоге вы потратите много времени, утверждая и убирая факты long (), которые вам понадобятся для отслеживания длины, но большинство из них "отменит". Более эффективный подход состоял бы в том, чтобы отозвать исходную функцию long (), затем передать длину в качестве аргумента и только повторно утверждать новую long, когда вы закончите. Но сделайте это, прежде чем беспокоиться об оптимизации!

0 голосов
/ 05 января 2012

Для начала:

  1. Проверьте, идет ли вставленный элемент в конец; если это так, вы можете использовать свой текущий код.
  2. Если он НЕ УДАЕТСЯ в конце: удалите (но помните!) Тот, который в данный момент находится в конце, рекурсивно попробуйте вставить новый элемент, а затем добавьте удаленный элемент к текущему концу (который может быть сделано с использованием вашего кода).
...