Prolog how to save file in an existing file - file

How do I save on an existing file after adding new data
add_a_link(X,Y) :-
tell('alink.txt'),
write(X),
write('.'),
write(Y),
write('.'),
put(10),
told,
write('data written'),
nl.
this code only re-write the text file.

Use open/3 and stream oriented I/O:
open(file, append, S), write(S, info(X,Y)), put_char(S,.), nl(S), close(S).
Using tell/1 and told is extremely unreliable. It easily happens that the output is written to another file accidentally.
Edit: Here is an example to illustrate the extremely unreliable properties of tell/1 and told.
Say, you write tell(file), X > 3, write(biggervalue), told. This works fine as long as X > 3. But with a smaller value this query fails and nothing is written. That might have been your intention. However, the next output somewhere else in your program will now go into the file. That's something you never want to happen. For this reason ISO-Prolog does not have tell/1 and told but rather open/3 and close/1.

Related

Prolog - load 2D array from text file into program

I'm currently working on a Prolog program which would, logically, have some kind of "save/load" feature. I've gotten the save part to work, where I'm now (as a start) creating three *.txt files, which will contain a 2D array/list each. However, I'm facing some issues trying to load it back into the program.
What I have right now is something as simple as:
% Initialize globals
?- nb_setval(aisles_global, []).
% Load all previously saved data from the given .txt files
load_all():-
exists_file('C:\\Users\\Xariez\\Desktop\\aisles.txt'),
open('C:\\Users\\Xariez\\Desktop\\aisles.txt', read, InAisles),
read_line_to_codes(InAisles, AisleString),
% read_line_to_string(InAisles, AisleString),
writeln(AisleString),
nb_setval(aisles_global, AisleString),
close(InAisles).
As previously mentioned, the files will have a 2D array each, but as an example:
aisles.txt
[["Beer", "Cider" ], [ "Milk", "Juice" ], ["Light Bread", "Dark Bread"]]
I've tried using both read_line_to_codes/2 and read_line_to_string/2. While it technically works when reading it into codes, I feel like it would quickly become annoying to reconstruct a 2D list/array since it's now got every character as a code. And while reading into a string succeeds in the reading part, we now have a string that LOOKS like a list, but isn't really one (if I've understood this situation correctly?). And hence I'm here.
If anyone got any ideas/help, that'd be greatly appreciated. Thanks!
Prolog has predicates for doing input/output of terms directly. You don't need to roll these yourself. Reading terms is done using read, while for writing there are several options.
Your best shot for writing is probably write_canonical, which will write terms in "canonical" syntax. This means that everything is quoted as needed (for example, an atom 'A' will be printed as 'A' and not as plain A like write would print it), and terms with operators are printed in prefix syntax, which means you get the same term even if the reader doesn't have the same operators declared (for example, x is y is printed as is(x, y)).
So you can write your output like:
dump(Aisles, Filename) :-
open(Filename, write, OutAisles),
write_canonical(OutAisles, Aisles),
write(OutAisles, '.'),
close(OutAisles).
Writing the . is necessary because read expects to read a term terminated by a period. Your reading predicate could be:
load(Aisles, Filename) :-
open(Filename, read, InAisles),
read(InAisles, Aisles),
close(InAisles).
Running this using some example data:
?- aisles(As), dump(As, aisles).
As = [["Beer", "Cider"], x is y, 'A', _G1380, ["Milk", "Juice"], ["Light Bread", "Dark Bread"]].
?- load(As, aisles).
As = [["Beer", "Cider"], x is y, 'A', _G1338, ["Milk", "Juice"], ["Light Bread", "Dark Bread"]].
The contents of the file, as you can check in a text editor, is:
[["Beer","Cider"],is(x,y),'A',_,["Milk","Juice"],["Light Bread","Dark Bread"]].
Note the canonical syntax for is. You should almost certainly avoid writing variables, but this shouldn't be a problem in your case.

How to read from a specific line from a text file in VHDL

I am doing a program in VHDL to read and write data. My program has to read data from a line, process it, and then save the new value in the old position. My code is somewhat like:
WRITE_FILE: process (CLK)
variable VEC_LINE : line;
file VEC_FILE : text is out "results";
begin
if CLK='0' then
write (VEC_LINE, OUT_DATA);
writeline (VEC_FILE, VEC_LINE);
end if;
end process WRITE_FILE;
If I want to read line 15, how can I specify that? Then I want to clear line 15 and have to write a new data there. The LINE is of access type, will it accept integer values?
Russell's answer - using two files - is the answer.
There isn't a good way to find the 15th line (seek) but for VHDL's purpose, reading and discarding the first 14 lines is perfectly adequate. Just wrap it in a procedure named "seek" and carry on!
If you're on the 17th line already, you can't seek backwards, or rewind to the beginning. What you can do is flush the output file (save the open line, copy the rest of the input file to it, close both files and reopen them. Naturally, this requires VHDL-93 not VHDL-87 syntax for file operations). Just wrap that in a procedure called "rewind", and carry on!
Keep track of the current line number, and now you can seek to line 15, wherever you are.
It's not pretty and it's not fast, but it'll work just fine. And that's good enough for VHDL's purposes.
In other words you can write a text editor in VHDL if you must, (ignoring the problem of interactive input, though reading stdin should work) but there are much better languages for the job. One of them even looks a lot like an object-oriented VHDL...
Use 2 files, an input file and an output file.
file_open(vectors, "stimulus/input_vectors.txt", read_mode);
file_open(results, "stimulus/output_results.txt", write_mode);
while not endfile(vectors) loop
readline(vectors, iline);
read(iline, a_in);
etc for all your input data...
write(oline, <output data>
end loop;
file_close(vectors);
file_close(results);

Unknown Master List .dat file, issues retrieving information

I come to you completely stumped. I do some side work for a company that uses an old DOS based program to input and retrieve data. This is a legacy piece of software, and they have since moved to either QuickBooks or Outlook for all of their address or billing related needs. However there have been some changes made, and they work with this database fairly regularly. Since the computer that this software is on, is running XP (and none of the other computers in the office can run it) they're looking to phase this software out for when the computer inevitably explodes.
TLDR; I have an old .csv file (roughly two years) that has a good chunk of information on it, but again it's two years old. I have another file called ml.dat (I'm assuming masterlist.dat) that's in the same folder as this legacy software. I open it with notepad and excel and am presented with information like this:
S;Û).;PÃS;*p(â'a,µ,
The above chunk of text is recognized much less within notepad or excel. It's a lot more of the unrecognized squares.
Some of the information is actually readable however. I can for example read the occasional town name, or person's name but I'm unable to get all of the information since there's a lot missing. Perhaps the data isn't in unicode or something? I have no idea. Any suggestions? I'm ultimately trying to take this information and toss it into either quickbooks or outlook.
Please help!
Thanks
Edit: I'm guessing the file might be encrypted since .dat's are usually clear text? Any thoughts?
.DAT files can be anything, they are usually just application data. Since there is readable text, then it is very unlikely that this file is encrypted. Instead you are seeing ASCII representations of the bytes of other content. http://www.asciitable.com/ Assuming single byte values, the number 77 might appear in the file somewhere as M.
Your options:
Search for some utility to load and translate the dat file for that application.
Set up an appropriate dos emulator so you can run this application on another box, or even a virtual machine running freedos or something.
Figure out the file format and then write a program to translate the data.
For #3, you can attach a debugger to the application to trace how the file is read and written. Alternatively you can try to figure out record boundaries (if all the records are the same size, then things are a little bit easier.) Then you can use known values to try to find field boundaries. If you can find (or reverse compile) the source code, then that could also give you insight into the file format.
1 is your best bet, and #2 will buy you some time so that you don't need that original machine anymore. #3 would likely be something to outsource.
If you can find the source or file format, then you just recreate whatever data structure was dumped to the file and read the file into it.
To find which exe opens it, you can do something like:
for %f in (*.exe) do find "ml.dat" %f -c
Assuming the original application was written in C then there would be code something like this to read the first record from the file:
struct SecretData
{
int first;
double money;
char city[10];
};
FILE* input;
struct SecretData secretdata;
input = fopen("ml.dat", "rb");
fread(&data, sizeof(data), 1, input);
fclose(input);
(The file would have been written with fwrite.) Basically you need to figure out the innards of the SecretData structure to be able to read the file.
There likely wasn't a separate utility used to make the file, dumping data and reading it back from a file is relatively easy in most languages.

How to find word from the end of file in Lua

Ok I use method from here: How to Read only the last line of a text file in Lua?
The problem is that sometimes line can be bigger.
The question is how can i find first word "foo" from the end of file and then use everything after it?
The problem is that sometimes line can be bigger.
Then you just need to seek further back from the end.
The question is how can i find first word "foo" from the end of file and then use everything after it?
Grab a big enough chunk of the file to be sure you've got the last foo, the use .*foo to skip everything up to and including the last "foo" (.* is greedy).
local f = io.open('filename', 'r')
f:seek('end', -1024)
local text = f:read('*a')
local after = string.match(text, ".*foo(.*)")
f:close()
If the file is not too big and you're ready to take the easy way out this might help:
fh=io.open('myfile.txt','rb')
str=fh:read'*a'
pat='foo'
afterFoo=str:match('.*'..pat..'(.*)$')
fh:close()
If you need a more complex, but faster (in run time on large files) solution, my guess would be that you' read in the file in chunks, reverse each of them, and look for your pattern in reverse. Don't forget to look for your pattern across the borders (the chunks must overlap at least the length of the pattern you're seeking in the general case).
For more explanation about the block reading, see my post here.

Lua file reading and writing error

Sorry if there's already a topic like this, but I couldn't find any that have something to do with Lua... So I'm basically having some problems in writing and reading files, here's what I've done:
hp = 25
file = io.open("player.txt","w")
if file==nil then
io.output("player.txt")
io.close()
end
file:write(hp)
file:close()
and it seems to work fine, it's just perfect... but then when I'm trying to add the file:write(hp) inside the if-sentence, it doesn't work. Also if I'll add file:read("*line") right after file:write(hp), this is what it says in player.txt:
25b[NUL]ÈñZ[NUL]
file = io.open("player.txt","w")
So what am I doing wrong? Also [NUL] is black block with white "NUL" text in it in notepad++ but it can't be copied here.
Edit: Hmmh, seems like the whole code is messed, up it always rewrites the whole file ;o
Edit2: Had actually no idea what I was talking about, nowadays I can understand file controlling bit more, here's what it should've been or what I tried to do:
function existsFile(path)
x = io.open(path)
if x == nil then
io.close()
return false
else
x:close()
return true
end
end
if not existsFile("player.txt") then
file = io.open("player.txt", "w")
file:write(25)
hp = 25
file:close()
else
file = io.open("player.txt", "r")
hp = file:read("*number")
file:close()
end
And I know it doest look anything like the code I first posted, but that's what I basically meant.
Could you explain what you are trying to do in this code?
Why do you need to check if file is nil? When you open file for writing, lua automatically creates it if not exists.
"w" mode means, that you you're erase all data in file and write new data
May be you need "a" mode? In this mode new lines are added at the end of file.
Sounds like you're confused about the flags on io.open. Check the manual to be sure what you really want is the w flag since that overwrites everything.
Trying to do a file:write when you're in the if shouldn't work, and I'm not sure why you'd expect it to, since file is nil. You're saying that if the file couldn't be opened, then try to write this to the file, which doesn't make sense to me.
The "if" block checks if "file" is nil, so that code block will never run.
read() doesn't work because you opened the file in "w" (write) mode.
Erasing the whole file is the expected behavior of write mode. In that mode the file is first erased and then you write new data to it.

Resources