2016-07-09 6 views
3

Wenn in der Befehlszeile lief, dieseQuerying vom Terminal druckt nicht alles

swipl -g "write(42)" -t "halt" 

druckt 42 bis STDOUT wie erwartet.

Doch diese

swipl -g "X = 42" -t "halt" 

nichts gedruckt wird, gibt es einfach.

Wie bekomme ich es zu drucken, was es in der REPL (das heißt X = 42) druckt?

Hinweis: Dies ist in einem Windows-Terminal. Lassen Sie mich wissen, ob das tatsächlich in einem Linux-Terminal funktioniert.

+0

Spielen mit 'with_output_to/2' scheint nichts zu tun – Fatalize

+0

" * 42 wie erwartet auf STDOUT gedruckt. * "Nichts mehr?Was ist mit "wahr" oder "ja"? – repeat

+0

@repeat es druckt nicht wahr, das ist wahrscheinlich das exakt gleiche Problem, das passiert, wenn es 'X = 42' nicht druckt. Grundsätzlich scheint es, dass alles explizit auf STDOUT ausgedruckte zwar gedruckt wird, aber alles "von der REPL" nicht gedruckt wird. – Fatalize

Antwort

4

Wie erwartet X = 42 von selbst erzeugt keine Ausgabe haupt, weil (=)/2 ein völlig reines Prädikat ist, die keine Nebenwirkungen von selbst nicht ergeben. Dies ist der Fall bei Windows, OSX und allen anderen   Betriebssystemen.

Selbst wenn es eine Möglichkeit gäbe, die Toplevel-Ausgabe selbst zu erhalten und umzuleiten, bleibt die Tatsache, dass SWI   Änderungen unterliegt und Sie sich nicht darauf verlassen können, dass zukünftige Versionen sich genauso verhalten wie jetzt. Langfristig sind Sie wahrscheinlich besser dran, Ihren eigenen Toplevel zu rollen und genau die Ausgabe zu produzieren, die Sie wollen.

Es ist nicht so schwer, eigene Toplevel zu rollen. Der Trick besteht hauptsächlich darin, die variable_names/1 Option beim Lesen von Begriffen zu verwenden, damit Sie die Variable Namen verfolgen können, die Sie in Antworten anzeigen möchten. Hier ist ein sehr   simpel Start:

 
repl :- 
     read_line_to_codes(current_input, Codes), 
     read_term_from_codes(Codes, Term, [variable_names(NameVars)]), 
     call(Term), 
     report_bindings(NameVars). 
repl :- repl. 

report_bindings(NameVars) :- 
     phrase(bindings(NameVars), Bs), 
     format("~s", [Bs]). 

bindings([])   --> []. 
bindings([E])   --> name_var(E). 
bindings([E1,E2|Rest]) --> name_var(E1), ",\n", bindings([E2|Rest]). 

name_var(Name=Var) --> 
     format_("~w = ~q", [Name,Var]). 

format_(Format, Ls) --> 
     call(format_codes(Format, Ls)). 

format_codes(Format, Ls, Cs0, Cs) :- 
     format(codes(Cs0,Cs), Format, Ls). 

Beispiel:

 
?- repl. 
|: X = 4, between(1, 3, Y). 
X = 4, 
Y = 1 
true ; 
X = 4, 
Y = 2 
true ; 
X = 4, 
Y = 3 
true ; 
|: X = 7. 
X = 7 

Es ist leicht, dies zu ändern, so dass es zu Bedingungen arbeitet, die als   Argumente angegeben werden.

Beachten Sie, dass die variable_names/1 Option zum Lesen von Begriffen in einer solchen Art und Weise, und dank der ISO   Standardisierungsbemühungen eine wachsende Zahl von Implementierungen für read_term/2 und damit verbundene Prädikate wesentlich ist.

Diese Fähigkeit zum Lesen von Variablennamen ist Anforderung für die Implementierung eines tragbaren Prolog Toplevel! Die Hauptübung, die ich für Sie hinterlasse, ist zu prüfen, ob die quoting in allen Fällen richtig ist und (falls gewünscht), Antworten auf eine solche Weise zu produzieren, dass sie immer wieder auf dem Terminal eingefügt werden können. Verwenden Sie Constraints, verwenden Sie copy_term/3 und call_residue_vars/2, um ausstehende Einschränkungen zu erfassen, die Sie den Bindungen hinzufügen können.

+2

Das scheint eine Menge Arbeit für etwas, das in erster Linie funktionieren sollte. Was ist der Punkt, wenn Sie Abfragen außerhalb der REPL ausführen können, wenn Sie die Ergebnisse nicht sofort aus der Box erhalten? – Fatalize

+3

Nun, das Ausführen eines einzelnen Ziels in der Befehlszeile unterscheidet sich einfach von einer REPL, und normalerweise möchten Sie keine REPL-Interaktion, wenn Sie SWI von einem Shell-Skript ausführen. Bisher gab es nur wenige Fälle, in denen es sich gelohnt hätte die REPL aussortieren. Ich stimme zu, dass es modularer sein sollte, und in der Tat hoffe ich, dass wir gemeinsam an einer modularen REPL arbeiten können, die auch in anderen Fällen nützlich wäre, in denen eine Interaktion mit dem Prolog-Interpreter stattfindet! Ich denke, es ist nicht so schwierig, eine einfache REPL zu bekommen, und ich hoffe, dass Sie in Erwägung ziehen, dieses Ende von dort aus fortzusetzen. – mat

+2

Vergessen Sie nicht, lesbare Variablen mit der Schreiboption 'variable_names/ 1' zu schreiben! – false

Verwandte Themen