2016-07-09 14 views
0

Man kann leicht eine Prolog-Datei unter Verwendung consult/1 oder [filename]. konsultieren.Beratung eines Atoms

Angenommen, ich erzeuge Prolog Code als ein Atom. Ich kann in einem Prädikat diesen Code in eine Datei schreiben und dann konsultieren und ein Prädikat aus diesem Code abfragen, z.

example :- 
    generate_stuff(X), 
    write_to_file(X,'filename.pl'), 
    consult('filename.pl'), 
    predicate_in_filename. 

Wie würde ich das gleiche tun gehen über, aber ohne X (der Code) in eine Datei zu schreiben? Ich habe kein Glück mit assert, die einen Begriff als Eingabe nimmt, während hier ich vollständigen Code in einem Atom habe.

+0

'consult' behauptet die Begriffe, die in' filename.pl' sind. Sie könnten ein Prädikat schreiben, das durch "X" analysiert und die Begriffe bestätigt. Es gibt viele Prolog-Unterstützungsprädikate, um Begriffe zu extrahieren. Es ist nicht klar, wie Sie insgesamt 'generate_stuff/1' strukturiert haben, aber es könnte sinnvoller erscheinen, wenn 'generate_stuff' die Begriffe bei ihrer Erstellung durchsetzt, anstatt sie alle als eine riesige Zeichenfolge zu sammeln und anschließend zu analysieren . – lurker

+0

@lurker Gibt es ein Prädikat, das 'X' in Terme zerlegt? "read_term_from_atom/3" analysiert nur die erste und es wäre mühsam für mich, etwas neu zu schreiben, das die Terme in einem Atom trennt. – Fatalize

+1

Wenn Sie Ihren Code strukturieren, um Ihre "Sachen" als eine große Zeichenfolge zu erstellen (was ich gegen wenn möglich empfehlen würde), dann sehen Sie sich den SWI-Prolog an (http://www.swi-prolog.org)/pldoc/man? section = termrw) Prädikate. Erwägen Sie, 'X' als Stream und nicht als Datei einzurichten. – lurker

Antwort

3

Der saubere Weg ist natürlich zu nicht sogar ein Atom an erster Stelle, sondern eine strukturierte Darstellung von Anfang an.

Wenn Sie jedoch Atome wirklich verwenden und sie später als strukturierte Begriffe behandeln möchten, verwenden Sie , und bestätigen Sie dann die Klausel.

Zum Beispiel:

 
?- atom_to_term('p(X, Y) :- dif(X, Y)', T, Vs). 
T = (p(_G925, _G926):-dif(_G925, _G926)), 
Vs = ['X'=_G925, 'Y'=_G926]. 

In Ihrem Fall Sie einfach Vs ignorieren kann:

 
?- atom_to_term('p(X, Y) :- dif(X, Y)', T, _). 
T = (p(_G916, _G917):-dif(_G916, _G917)). 
+0

Das Problem ist, wenn ich mehrere Begriffe im Atom habe? z.B. 'a. \ nb.''. Hier könnte ich auf neue Zeilen aufteilen und maplist atom_to_term, aber es ist nicht so einfach, wenn ich innerhalb der Begriffe auch Zeilenumbrüche habe (zur besseren Lesbarkeit). – Fatalize

+0

@Fatalize dann sehen Sie meinen letzten Kommentar zu Ihrer Frage. – lurker

+1

Sie sollten Ihre grundlegende Darstellung wirklich überdenken. Vermeiden Sie die Verwendung von Atomen für strukturierte Daten. Das gilt übrigens auch für Strings: Sie sind fast immer die falsche Darstellung. – mat

0

Für die Nachwelt hier ist, wie ich es getan hätte, vorausgesetzt, dass Sie nur einen Begriff in jeweils Atom der Liste:

%... 
maplist(read_term_from_atom_, ListOfAtoms, ListOfTerms), 
maplist(asserta, ListOfTerms), 
%... 

read_term_from_atom_(A, B) :- 
    read_term_from_atom(A, B, []). 
+0

Dies ist weniger allgemein als es sein könnte: Sie können '_' anstelle von '[]' verwenden und auch * Variablen * in den Klauseln zulassen. – mat