Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terminating [user]. with a EOT character in Prolog

Tags:

prolog

I am writing a wrapper for a Prolog interpreter used from a different programming language. I don't go into detail, but it basically generates a conforming Prolog program and feeds the program to an interpreter from the standard input. I am relatively new to Prolog.

The problem is, I could not find the specification for [user]. term that reads the rules from the standard input. Specifically, how it detects the end of the input.

The most intuitive way to achieve this is to send an EOT character (Ctrl-D), but it does not seem to work. Below is an illustrative example, replace the ^D with an actual EOT character. Assume this file is saved in input.pl. I intend to generate such code programatically and feed it to the background prolog process through the standard input.

[user].
factorial(0,1).
factorial(N,F) :- (>(N,0),is(N1,-(N,1)),factorial(N1,F1),is(F,*(N,F1))).
^D
factorial(3,W).

When I run cat input.pl | <prolog> where <prolog> is whatever Prolog interpreter (swipl, yap, etc.), it does not seem to recognize ^D. Why is this and how do I solve this? On the terminal ^D works fine.

Above example is supposed to return "W=6". SWI complains Syntax error: illegal_character. Yap seems to ignore ^D, just parse everything and return yes.

Of course I can write the program onto a temporary file and tell the interpreter to consult the file, but it is slow.

like image 829
Asai Masataro Avatar asked Nov 07 '17 05:11

Asai Masataro


People also ask

How to write one character at a time in Prolog?

We can use put (C) to write one character at a time into the current output stream. The output stream can be a file or the console. This C can be a character or an ASCII code in other version of Prolog like SWI prolog, but in GNU prolog, it supports only the ASCII value. To use the character instead of ASCII, we can use put_char (C).

How to get the EOT character in Linux terminal?

A real EOT can be received by typing Ctrl+V then Ctrl+D. The so - called "raw" mode of the terminal driver means, that it doesn't interpret control characters anymore, so the EOT character is sent to the program without any changes. The program may interpret it in any possible way.

How to return the input from the user in Prolog?

Before Prolog accepts the input from the user, we have to press the 'return' key. When Prolog evaluates a get0 goal, the variable is unified with the ASCII value of the input character.

Is there a way to stop EOT reading at EOL?

In particular, it doesn't apply to serial ports. There's no standard shell utility that stops reading at EOT or at a configurable character and accepts arbitrary binary input. If there are no null bytes in your input, you can use the head command or the read shell builtin to read one line after exchanging EOT with EOL:


1 Answers

Say end_of_file. in place of ^D. This works in many Prolog implementations because their actual reading is performed with read/1. Historically, from DECsystem 10 Prolog on, systems only had read/1 but did not have at_end_of_stream/0 and related built-in predicates. In fact, some programmers used end_of_file. within a Prolog source file to permit appending arbitrary text to a Prolog source.

like image 93
false Avatar answered Oct 03 '22 01:10

false