【问题标题】:Prolog - Insert with factsProlog - 插入事实
【发布时间】:2012-01-04 23:05:09
【问题描述】:

我需要在 Prolog 中编写一个谓词,在指定位置插入一个元素,从而修改列表中其余元素的位置编号。 我所实现的是下一个实现 Predicate 的代码 sn-p,该 Predicate 在列表末尾插入一个元素。 在数据库领域,除了 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

感谢任何帮助。

【问题讨论】:

  • 闻起来像家庭作业 :-)

标签: list insert prolog fact


【解决方案1】:

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

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

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

【讨论】:

  • 但是我想要增加“long”,因为我在列表中插入了一个新元素。
  • 最终,你会增加 long,但你必须先减少它,这样你才能将列表缩小到可以将你的添加添加到缩小列表末尾的点;一旦你的新人被添加,那么当你把你取下的物品放回新位置时,long 会恢复原状。
【解决方案2】:

让您开始:

  1. 检查插入的项目是否在最后;如果是这样,您可以使用您当前的代码。
  2. 如果它没有走到最后:删除(但记住!)当前位于末尾的项目,递归尝试插入新项目,然后将删除的项目添加到现在结束(可以是使用您的代码完成)。

【讨论】:

  • 是的,这就是重点。我知道如何在最后插入,但不知道如何在数据库中间插入。还是谢谢。
  • 如果我想在列表中间插入一个元素,你将如何更新列表的其余部分?我的意思是我们必须改变列表中每个元素的位置。你会在插入之前更新位置编号,从要插入的位置到列表的末尾,然后最后将元素插入到正确的位置吗?
  • 请注意,上面的大纲没有说明在中间插入:收回最后一个位于错误位置的事实,递归添加新事实,并重新声明您收回的事实(使用位置编号适合它的新位置,看起来比以前多了 1 个)。
  • 但是我应该实现它,就好像我不知道要插入新元素的位置之后的事实数量一样。我根据我留下的最后一条评论编辑了代码。
  • 你已经改变了你的插入子句,显然,现在的意思是什么。也许你应该通过 cmets 来解释它们?
【解决方案3】:

这是基本情况:

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

【讨论】:

  • 非常感谢您的帮助。然后我的问题是我什么时候必须递归调用?就在我插入新项目之后或最后,在放回删除的项目之后?
  • 递归调用处理插入新项目(这就是它的编写目的:将项目插入列表)。
  • 对不起。这是“我的最后一次尝试”部分
  • 顺便问一下,“更改事实以使列表 1 更短”是什么意思?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 2011-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多