List 序言-插入事实

List 序言-插入事实,list,insert,prolog,fact,List,Insert,Prolog,Fact,我需要在Prolog中编写一个谓词,在指定的位置插入一个元素,从而修改列表中其余元素的位置号。 我得到的是下一段代码,它实现了一个谓词,在列表的末尾插入一个元素。 在数据库部分,除了LIST之外,我们还有LONG,表示列表中元素的数量。 最后,在我的文章中有一些代码试图实现de谓词。谁能告诉我里面怎么了? 我在这里迷路了 Domains name=symbol position=integer element=integer Database list(name,position,ele

我需要在Prolog中编写一个谓词,在指定的位置插入一个元素,从而修改列表中其余元素的位置号。 我得到的是下一段代码,它实现了一个谓词,在列表的末尾插入一个元素。 在数据库部分,除了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
感谢您的帮助。

要开始学习:

  • 检查插入的项目是否位于末尾;如果是,您可以使用当前代码
  • 如果它没有在结尾:删除(但记住!)当前在结尾的项目,递归地尝试插入新项目,然后将您删除的项目添加到now结尾(这可以使用您的代码完成)
  • 以下是基本情况:

    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,将新项目插入其中,然后将删除的项目放回末尾。

    关于“我的最后一次尝试”:

  • 为什么你要收回你试图(最终)断言的事实清单
  • 您必须先缩短列表(即,收回最后一个元素并替换长度),然后才能执行递归(因为它必须在较短的列表上工作)

  • 注意:您最终将花费大量时间断言和收回long()事实,您需要跟踪这些事实的长度,但它们中的大多数将“取消”。一种更有效的方法是收回原来的long(),然后将长度作为参数传递,并且只在完成后重新断言新的long。但是,在您担心优化之前,让它工作起来吧

    闻起来像作业:-)是的,这就是重点。我知道如何插入数据库的末端,但不在数据库中间。无论如何,谢谢。如果我想在列表中间插入一个元素,你会如何更新列表的其余部分?我的意思是我们必须改变列表中每个元素的位置。在插入之前,您是否会更新位置号,从要插入的位置到列表的末尾,然后,最后,将元素插入到正确的位置?请注意,上面的大纲没有提到在中间插入:收回位于错误位置的最后一个事实,递归添加新事实,并重新声明您撤回的事实(位置编号与其新位置相匹配,看起来比以前多了1个位置)。但我应该实现这一点,就像我不知道插入新元素位置后的事实数量一样。我根据我留下的最后一条评论编辑了代码。您已经更改了insert子句,显然,也更改了long now的含义。也许你应该通过评论来解释它们?我非常感谢你的帮助。那么我的问题是什么时候我必须递归调用?就在我插入新项之后,或者在结束时,放回删除的项之后?递归调用处理插入新项(这就是它的编写目的:将项插入列表)。抱歉。这是“我最后一次尝试”一节顺便问一下,你说“改变事实,缩短列表1”是什么意思?谢谢,但我想增加“long”,因为我在列表中插入了一个新元素。最终,您将增加long,但您必须先减少它,以便将列表缩小到可以将添加的内容添加到缩小列表的末尾;一旦你的新家伙被添加,那么当你把你脱下的物品放回新的位置时,long将返回。