2016-06-17 15 views
0

Ich versuche, ein Prädikat replace(+OldFact,+NewFact) zu implementieren, die nur erfolgreich sind, wenn der OldFact vorhanden war. Wenn dies erfolgreich ist, muss die NewFact zur Menge der Klauseln hinzugefügt werden und der OldFact muss gelöscht werden.Prolog: Ersetzen Sie Fakt mit der Tatsache

Wie mache ich das? Ich bin nicht in der Lage, klar zu erkennen, dass, wie diese Ersetzung mit Fakten zu erreichen sowie die Verwendung dieser behaupten und zurückziehen Datenbank Manipulationsbefehle.

Danke.

+0

können Sie rufen 'OldFact 'um zu bestimmen, ob es in der Datenbank ist. 'call (OldFact)' wird erfolgreich sein, wenn es ist. Dann können Sie 'retract/1' und' astz/1' verwenden, um das zu tun, was Sie wünschen. Der Listen-Beispielcode, den Sie anzeigen, ist nicht relevant, es sei denn, Sie möchten eine Liste mit Ersatz- statt behaupteten Fakten haben. – lurker

+0

Sind Sie wirklich sicher, dass Sie Prolog-Prädikate ändern möchten? Ihre Definition sieht nicht so aus wie – false

+0

@lurker. Vielen Dank. Eigentlich ja, ich wollte die alte Tatsache durch eine neue Tatsache ersetzen. Und wenn die alte Tatsache in der Datenbank gefunden wird, dann wird sie gelöscht und eine neue Tatsache wird in die Datenbank eingefügt. Die Prädikat-Implementierung ist etwas wie: Ersetzen (Oldfact, NewFact). –

Antwort

1

Wenn ich die Anfrage bei Nennwert nehme, müssen Sie nur die Prädikate verwenden, die ich in meinem Kommentar erwähnte. Ihr Prädikat würde wie folgt aussehen:

replace_existing_fact(OldFact, NewFact) :- 
    ( call(OldFact) 
    -> retract(OldFact), 
     assertz(NewFact) 
    ; true 
    ). 

Ich gehe davon aus, dass, wenn die OldFact nicht gefunden wird, dann Sie das Prädikat einfach erfolgreich sein wollen. Wenn ein Fehler des Prädikats akzeptabel ist, wenn die alte Tatsache nicht existiert, würde dies einfach geschrieben werden:

replace_existing_fact(OldFact, NewFact) :- 
    call(OldFact), 
    retract(OldFact), 
    assertz(NewFact). 


Beachten Sie, wenn Sie mehr als eine gleiche OldFact in der Datenbank haben, wird dieses Prädikat Rückzieher für jeder, ersetzt ein Vorkommen auf jeder Rückspur. Wenn Sie nur eine von ihnen ersetzen möchten, können Sie einen Schnitt verwenden:

replace_existing_fact(OldFact, NewFact) :- 
    call(OldFact), !, % Don't backtrack to find multiple instances of old fact 
    retract(OldFact), 
    assertz(NewFact). 

Alternativ, wenn Sie jeden ersetzen möchten, ohne Rückzieher gefragt zu werden:

replace_each_existing_fact(OldFact, NewFact) :- 
    forall(replace_existing_fact(OldFact, NewFact), true). 
+0

Was ist, wenn es mehrere Fakten gibt, sagen wir 'f (1). f (1). – false

+0

@lurker. Ich danke dir sehr. Jetzt verstehe ich die Implementierung dieser Retract- und Assert-Befehle. Es wird mir viel weiter helfen, mehr Fragen zu lösen. –