print_term writing to a file in PROLOG - prolog

In this mcve]
test :-
tell('junk.txt'),
print_term(
examples([this,is,a,really,long,example,list],
[made,of,lists,atoms,and,including,terms(involving,parentheses,like,this)]),
[]),
told.
SWI-PROLOG does print the term to the screen neatly in the print_term way, but won't print it to the file. How do I redirect the output?

You may use current_output/1 to get the current Stream and then pass it to print_term/2 in its Options parameter:
test :-
tell('junk.txt'),
current_output(Stream),
print_term(
examples([this,is,a,really,long,example,list],
[made,of,lists,atoms,and,including,terms(involving,parentheses,like,this)]),
[output(Stream)]),
told.
I believe all those Edinburgh style predicates that deal with files are in maintenance mode and you now may prefer to use ISO stream predicates.

Related

How to check for empty Arguments in Prolog?

I'm new to prolog and could use some help.
Currently, I have to make a program that concat the last character of two strings.
For example,
?- termCat(with,spaghetti,T).
T=hi
I was wondering how can I account for one of the arguments being nonexistant.
For instance I'm hoping to catch something like this...
?- termCat( , spaghetti,T).
T = i
I use this pattern for 'default arguments' (the C++ feature, kind of). Depending on your use case and Prolog system, you should adapt as required. Beware that var/1, nonvar/1, !/0 are impure builtins that could interfere in unexpected ways with the resolution process. The cut (that is, !/0) is implicit in ->/2.
termCat(X,Y,T) :-
(var(X) -> X=with;true),
(var(Y) -> Y=spaghetti;true),
etc etc.
In SWI-Prolog, you can require arguments are not free - for instance - using assertion/1 from library(debug):
:- use_module(library(debug)).
termCat(X,Y,T) :-
assertion((nonvar(X),nonvar(Y))),
etc etc.

Prolog - Write out facts and reading a users input

I am quite new to Prolog and have had some trouble understanding it.
I have some facts named 'problem' I wish to first print out these facts to the user and then ask them to input a value, this value is then read and used later.
From my understanding thus far, it would be best to use a forall to print out these facts and then use read to read the value inputted, but I am having some issue implementing this. Here is what I have so far, any explanation would be appreciated
My question: How do I read in the input from the user regarding the problem and apply that into a variable for later use?
tellMeYourProblem:-
forall(problem(P),
writeln(P)),
answer = read(X),
problem('1').
problem('2').
problem('3').
problem('4').
problem('5').
problem('6').
problem('7').
problem('8').
problem('9').
problem('10').
Note: This answer uses SWI-Prolog.
How do I read in the input from the user regarding the problem?
You are doing that already with read(X), however read/1 reads terms (terms end with periods) and you probably want to read characters. If you are using SWI-Prolog take a look at Primitive character I/O for reading characters and Predicates that operate on strings for reading strings.
How do I apply that into a variable for later use?
When doing basic I/O with a user at a text level, a REPL is a good way to start. Adding a REPL is a bit more complicated so I will give you the code.
tellMeYourProblem :-
output_problems,
read_input.
output_problems :-
forall(problem(P),
writeln(P)).
read_input :-
repeat,
read_string(user_input, "\n", "\r\t ", _, Line),
process_input(Line).
process_input(Line) :-
string(Line),
atom_number(Line, N),
integer(N),
do_something_with(Line),
fail.
process_input("quit") :-
write('Finished'), nl,
!, true.
do_something_with(X) :-
writeln(X).
problem('1').
problem('2').
problem('3').
problem('4').
problem('5').
problem('6').
problem('7').
problem('8').
problem('9').
problem('10').
Also with Prolog, the style is to use snake casing so tellMeYourProblem should be tell_me_your_problem.
Normally in Prolog a REPL is done with ->/2, (Read Input till quit statement Prolog) , but I changed this to add more guard statements so that the exit condition would work, e.g.
string(Line),
atom_number(Line, N),
integer(N)
or putting the guard in the head, e.g.
process_input("quit")
When doing I/O to a screen and keyboard, the thought is to use stdIn and stdOut but for the keyboard SWI-Prolog uses user_input instead. See: Input and output
After all of the boiler plate code for the REPL is the next part you seek which is to do something with the input value, in this case just print it out.
do_something_with(X) :-
writeln(X).
The easiest to write out the facts of problem/1,
is to use the builtin listing/[0,1]. This builtin
accepts a so called predicate indicator. You can
write out the facts via:
?- listing(problem/1).
The predicate is supported by many Prolog systems
such as GNU Prolog, etc.. For how to read input see
for example the post by Guy Coder.

Using the prolog format predicate to print to file

Is it possible to use the prolog format predicate to print to file?
I have a table of data that I print to stdout using the format predicate, i.e.
print_table :-
print_table_header,
forall(range(1.0,10.0,0.1,N), print_row(N,L)).
%% print_row(L) :- take a list of the form, [a,b,c,d,e] and
%% print it to screen as a single row of tab separated float values (1DP)
print_row(N,L) :-
build_row(N,L),
format('~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~n', L).
print_table_header :-
format('~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~n', ['N','N2','N3','N4','N5']).
would be nice to somehow reuse the code to print the same thing to file.
In addition to the other good answer (+1!), I would like to present a purer solution to such tasks.
The key idea is to make format/2 accessible within DCGs, and then to use a DCG to describe the output.
This is very easy, using the codes argument of format/3, provided by several Prolog implementations. All you need are the following short auxiliary definitions:
format_(Data, Args) --> call(format_dlist(Data, Args)).
format_dlist(Data, Args, Cs0, Cs) :- format(codes(Cs0,Cs), Data, Args).
The nonterminal call//1 calls its argument with two additional arguments that let you access the implicit DCG arguments, and this is used to describe additional codes via format/3.
Now, we can simply use the nonterminal format_//2 within DCGs.
For example, to describe a simple table:
table -->
row([a,b,c]),
row([d,e,f]).
row(Ls) --> format_("~t~w~10+~t~w~10+~t~w~10+~n", Ls).
Usage example and result:
?- phrase(table, Cs), format("~s", [Cs]).
a b c
d e f
Cs = [32, 32, 32, 32, 32, 32, 32, 32, 32|...].
Note that one last remaining format/2 is used to actually write the output to the screen.
However, everything else is free of side-effects and declaratively describes a table.
An important advantage of this method is that you can easily write test cases to see whether your tables are (still) correctly formatted. It is easy to reason about Prolog lists of codes (described with a DCG), but quite hard to reason about things that only appear on the terminal.
You can!
Consider the following extract of the SICStus Prolog documentation for format/[2,3]:
11.3.85 format/[2,3]
Synopsis
format(+Control, +Arguments)
format(+Stream, +Control, +Arguments)
Interprets the Arguments according to the Control string and prints the result on Stream.
The predicates format/[2,3] are widely supported across Prolog implementations.
However, as of right now, these predicates are not part of ISO Prolog.
I would write the output 'routines' with an additional parameter, a Stream, and then I would pass user while testing or printing to screen. See ISO predicates open/3, close/1 etc for stream handling...
Note that IO it's among the least 'declarative' areas of the language, because, for efficiency, an approach based on side effects is required...
SWI-Prolog has a builtin with_output_to, that would allows to reuse your existing code without adding a parameter. But since you tagged iso-prolog your question, you should really add the Stream parameter...

Defining predicates in SICStus Prolog / SWI-Prolog REPL

I am reading http://cs.union.edu/~striegnk/learn-prolog-now/html/node3.html#subsec.l1.kb1,
but I am having trouble running the following predicate:
SICStus 4.0.1 (x86-win32-nt-4): Tue May 15 21:17:49 WEST 2007
| ?- woman(mia).
! Existence error in user:woman/1
! procedure user:woman/1 does not exist
! goal: user:woman(mia)
| ?-
If, on the other hand, I write it to a file and run consult the file, it seems to work fine...
Am I only allowed to define predicates in a file having later to consult them? Can't I just do it in the editor itself?
It's a little annoying to make predicates in the repl. You could do
| ?- ['user'].
woman(mia).
^D
ie consult user input, or
| ?- assertz(woman(mia)).
assert it. Both awkward IMO -- there might be a better way, though, I just don't know it. In general it is easier to use a script.
You should enter woman(mia). into a file to assert it as a fact. If you write it into the interpreter, it's taken as a query, not a fact.
From the SWI Prolog FAQ:
Terms that you enter at the toplevel are processes as queries, while
terms that appear in a file that is loaded into Prolog is processed as
a set of rules and facts. If a text reads as below, this is a rule.
carnivore(X) :- animal(X), eats_meat(X).
Trying to enter this at the toplevel results in the error below. Why?
Because a rule is a term :-(Head, Body), and because the toplevel
interprets terms as queries. There is no predicate with the name :-
and two arguments.
?- carnivore(X) :- animal(X), eats_meat(X). ERROR: Undefined
procedure: (:-)/2 ERROR: Rules must be loaded from a file ERROR:
See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
Isn't this stupid? Well, no. Suppose we have a term
eats_meat(rataplan). If this appears in a file, it states the fact
that rataplan eats meat. If it appears at the toplevel, it asks Prolog
to try proving whether rataplan eats meat.
If a text reads
:- use_module(library(clpfd)).
This is a directive. Directives are similar to queries, but instead of
asking the toplevel to do something, they ask the compiler to do
something. Like rules and facts, such terms belong in files.
Instead of writing to a file you can also use assert in the toplevel (as explained later in the FAQ as well).

How to define a predicate in prolog

I am new to Prolog and I have so far learned how to define a predicate in a file and the run the interpreter to use it. But I would like to know if there is a way to define the predicate at the ?- prompt so that I don't have to switch back and forth.
the way I am doing it now is like this
file defs.pl:
adjacent(1,2).
adjacent(1,3).
in the prolog interpreter:
?- consult('defs.pl').
% defs.pl compiled 0.00 sec, 122 bytes
true.
?- adjacent(1,2).
true.
EDIT
maybe I meant how to define 'facts' I'm not sure.
You can use the assert/1 predicate:
?- assert(adjacent(1,4)).
true
EDIT:
By the way, this will not work if you try to combine it with predicates defined in a file.
So either define all adjacent/2 predicates in your file, are define them all with assert in the command line.
If you do want to define some of the predicates in the file, and others with assert, then declare in your file that the predicate is dynamic:
% file contents
:- dynamic(adjacent/2).
adjacent(1,2).
adjacent(1,3).
You can do
?- consult(user).
or
?- [user].
and enter the clauses after that, then terminate the input with the end of file character (Ctrl-D in Linux, could be Ctrl-Z in MS-Windows). This is equivalent to reading a file, see the documentation of consult/1.
assert/1 and retract/1 are intended for predicates that are changed dynamically by the code (i.e. for storing global data), not for normal programming.

Resources