2010-06-28 1 views
10

Gibt es eine Möglichkeit, Konstanten in Prolog zu definieren?Prolog Konstanten

Ich möchte etwas schreiben, wie

list1 :- [1, 2, 3]. 
list2 :- [4, 5, 6]. 

predicate(L) :- append(list1, list2, L). 

Die Work-around Ich verwende jetzt ist

list1([1, 2, 3]). 
list2([4, 5, 6]). 

predicate(L) :- 
    list1(L1), 
    list2(L2), 
    append(L1, L2, L). 

aber es ist ein bisschen ungeschickt eine „nutzlose“ Variable wie diese zu binden jedes Mal muss ich auf die Konstante zugreifen.

Eine andere (noch hässlicher) Arbeit um, nehme ich an, wäre cpp in die Bau-Kette aufzunehmen.

(In meinem tatsächlichen Anwendung ist die Liste eine große LUT an vielen Orten verwendet.)

+3

Das ist kein Workaround. Das nennt man Faktenerklärung. Sie erklären die Tatsache, dass "list1/1" ein sukzessives Ziel ist, wenn das Argument "[1,2,3]" lautet. Da es keine Variablen in Prolog gibt, können Sie davon ausgehen, dass jeder "Wert" (Atom oder Term) konstant ist und jede "Variable" (Wertname) eine Konstante ohne Determinit ist. Jede "Variable" (z. B. "L1") kann sogar "(1 + 2 * 3)" enthalten und wird niemals interpretiert, da es sich um etwas wie "(1+ (2 * 3))" handelt Tatsache '(7 ist (1+ (2 * 3)).'). Wenn Sie 'list1' als Argument von append übergeben, wird es als atom interpretiert. Sie können' myappend (list1, list2, [1,2,3 , 4,5,6]). ' – ony

+0

Ich * benutze * fact-declaration als ein Workaround, um keine Konstanten zu haben. – aioobe

Antwort

11

Ich glaube nicht, dass Sie in ‚reinen‘ Prolog tun können (obwohl einige Implementierungen Sie in der Nähe etwas tun können lassen ZB hat ECLiPSe Regale).

Der Grund dafür ist:

1) Sie nicht Dinge wie

list1 :- [4, 5, 6]. 

oder

list1 = [4, 5, 6]. 

Weil die rechte Seite und die linke Seite der beiden Gründe sind schreiben können Begriffe die nicht übereinstimmen.

2) Sie können nicht Dinge schreiben wie

List1 :- [4, 5, 6]. 

oder

List1 = [4, 5, 6]. 

weil die linke Seite jetzt eine Variable, aber Variablen sind nur in Prädikat Köpfe/Körper erlaubt .

Was Sie könnte tun, ist ein Multi-Option Prädikat wie definieren:

myList([1, 2, 3]). 
myList([4, 5, 6]). 

und dann abrufen alle ihre Werte mit bagof (oder ähnliche Prädikate):

predicate(L) :- 
    bagof(ML, myList(ML), MLs),   
    concat(MLs, L). 

MLs ist Die Liste aller ML Werte, die myList(ML) und natürlich concat erfüllen, verkettet eine Liste von Listen.

+0

Ich stimme deiner Antwort zu und denke, dass man Grundbegriffe wie' p ([1,2, 3]). 'Oder 0-arity-Begriffe wie' x.' ist im Allgemeinen der Weg zu definieren _global_ Konstanten in PROLOG, und solche Begriffe zu verwenden, wenn lokal in der Definition von Prädikaten, die etwas wie 'List1 = [ 4, 5, 6] 'wie ein Unterziel (wie Sie erwähnt haben). – sharky

+0

sollte nicht ein Komma am Ende des BagoStestement sein? Ich bin nicht in der Lage, MLs in eine einzige Liste zu bekommen. –

+0

@PulkitVerma, klingt richtig, bearbeitet. – Mau

2

Nein, das kann man in Prolog nicht machen, und es über ein Prädikat zu definieren, ist die vernünftige Sache.

Oder besser, kapseln Sie Ihre Lookup-Funktion in einem Prädikat.

Das heißt, wenn Sie wirklich Vorverarbeitung verwenden möchten, gibt es term_expansion/2, aber es kann Ihren Code unlesbar und unordentlich machen, wenn Sie nicht vorsichtig sind.

Sie könnten auch in Erweiterungen von Prolog suchen, die Funktionsnotation enthalten (funktionale Logiksprachen wie Mercury). Aber diese sind noch exotischer als Prolog.