Как и следовало ожидать, X = 42
сам по себе не вызывает никакого вывода бы то ни было, потому что (=)/2
является полностью чистым предикат, который не дает никаких побочных эффектов сам по себе. Это касается Window, OSX и всех других операционных систем .
Даже если бы существовал способ получить и перенаправить выход верхнего уровня, факт остается фактом: SWI может быть изменен, и вы не можете полагаться на будущие версии, чтобы вести себя так же, как сейчас. В долгосрочной перспективе вам, скорее всего, будет лучше сдать ваш собственный toplevel и произвести именно то, что вы хотите.
Не так сложно катить свой собственный верхний слой. Фокус в основном заключается в использовании опции variable_names/1
при чтении терминов, чтобы вы могли отслеживать переменные имена, которые вы хотите показать в ответах. Вот очень упрощенный старта:
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).
Пример:
?- 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
Легко изменить это так, что он работает на условиях, которые определены в качестве аргументов.
Обратите внимание, что вариант variable_names/1
имеет важное значение для чтения условия таким образом, и благодаря усилиям по стандартизации ISO все большее число реализаций обеспечивает его read_term/2
и связанные с предикатами.
Эта способность читать имена переменных - это требование для реализации портативного Prolog toplevel!
Главное упражнение, которое я оставляю для вас, это проверить, действительно ли , цитируя, во всех случаях и (при желании) для получения ответов таким образом, чтобы их всегда можно было наклеить обратно на терминал. Чтобы распространить это на остаточные ограничения, используйте copy_term/3
и call_residue_vars/2
для сбора ожидающих ограничений, которые вы можете добавить к привязкам.
Игра с 'with_output_to/2', кажется, ничего не делает – Fatalize
" * Распечатывает 42 в STDOUT, как ожидалось. * "Больше ничего?Как насчет «истинного» или «да»? – repeat
@repeat не печатает true, что, вероятно, является той же самой проблемой, которая возникает, когда она не печатает 'X = 42'. в основном, кажется, что все напечатанные явно STDOUT действительно напечатаны, но все, что «напечатано REPL», нет. – Fatalize