2016-07-09 1 views
3

Когда побежал в командной строке, этоЗапросы от терминала не печатает ничего

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

печатает 42 до STDOUT, как и ожидалось.

Однако это

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

ничего не печатает, он просто возвращает.

Как его распечатать, что он печатает в REPL (то есть, X = 42)?

Примечание: это находится в терминале Windows. Дайте мне знать, действительно ли это работает на терминале Linux.

+0

Игра с 'with_output_to/2', кажется, ничего не делает – Fatalize

+0

" * Распечатывает 42 в STDOUT, как ожидалось. * "Больше ничего?Как насчет «истинного» или «да»? – repeat

+0

@repeat не печатает true, что, вероятно, является той же самой проблемой, которая возникает, когда она не печатает 'X = 42'. в основном, кажется, что все напечатанные явно STDOUT действительно напечатаны, но все, что «напечатано REPL», нет. – Fatalize

ответ

4

Как и следовало ожидать, 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 для сбора ожидающих ограничений, которые вы можете добавить к привязкам.

+2

Это похоже на большую работу за то, что должно работать в первую очередь. Какой смысл запускать запросы вне REPL, если вы не можете получить результаты этого из коробки? – Fatalize

+3

Ну, выполнение одной цели в командной строке просто отличается от REPL, и обычно вы не хотите взаимодействия REPL при запуске SWI из сценария оболочки, поэтому пока что было всего несколько экземпляров, где было бы полезно чтобы исключить REPL. Я согласен, что он должен быть более модульным, и на самом деле я надеюсь, что мы сможем работать над более модульным REPL, который также будет полезен в других случаях, когда происходит взаимодействие с интерпретатором Prolog! Я думаю, что получение базового REPL работает не так сложно, и я надеюсь, что вы решите продолжить эту работу. – mat

+2

Не забудьте написать читаемые переменные, используя параметр write 'variable_names/1'! – false

Смежные вопросы