Delo z datotekami v prologu
Iz E-študij, proste zakladnice študentskega znanja
- Članek govori o delu z datotekami v Prologu.
?- consult(Ime_datoteke).
?- reconsult(Ime_datoteke).
Vsebina |
Tokovi
See
Vhodni tok podatkov
- see
- odpre datoteko za branje oz. (če je že odprta) prenesi vhodni tok na to datoteko
- user
- prenese tok podatkov nazaj na uporabnika
- seeing
- preverimo kateri je trenutni vhodni tok podatkov (ime datoteke ali "user")
see(Ime_datoteke), see(user), seen, seeing(Ime_datoteke)
Tell
Izhodni tok podatkov (podobno kot see)
tell(Ime_datoteke), tell(user), told, telling(Ime_datoteke)
Branje znakov
- get0
- prebere trenutni znak pri trenutnem vhodnem toku podatkov in vrne njegovo ASCII kodo
- get
- preskoči vse nevidne znake
- put
- predpostavi da je element celo število (ASCII koda) katerega znak izpiše na trenutni izhodni tok podatkov
get0(Znak), get(Znak), put(znak)
Primeri
Branje iz datoteke
daj_znak(Dat):- see(Dat), %odpremo datoteko get0(Znak), %preberemo prvi znak datoteke put(Znak), %izpišemo znak na trenutni izhodni tok podatkov see(user). %povrnemo tok branja na terminal
Vpisovanje v datoteko
vpisi_znak(Dat) :- get0(Znak), tell(Dat), put(Znak), tell(user).
Kopiranje datoteke
kopiraj(Vhod,Izhod):- see(Vhod), tell(Izhod), kopiraj, seen, told. kopiraj:- get0(Ch), put(Ch), kopiraj. kopiraj.
Iterativno kopiranje
kopiraj_it :- repeat, kopiraj_znak. repeat. repeat:-repeat. kopiraj_znak :- get0(Ch), %rez prepreči izvajanje drugega stavka !, %če get0 uspe (še ni konec datoteke) put(Ch), fail. %fail nikoli ne uspe kopiraj_znak.
Branje datotek
Read
Ukaz read prebere iz trenutnega toka podatkov celotni (sintaktično pravilen) izraz pri katerem predpostavi, da se izraz zaključi s piko in enim nevidnim znakom. Pika samo zaključi izraz, zato pika ni del izraza.
read(Term), end_of_file
Write
Ukaz write izpiše trenutno vrednost s katero je prilagojena spremenljivka.
write(Term)
Primer
?- roditelj(X,leo). X = lili yes
lahko zapišemo tudi kot
daj_roditelja :-
write('cigavega roditelja zelis?),
read(Otrok),
roditelj(Roditelj,Otrok),
write('roditelj od '),
write(Otrok),
write(' je '),
write(Roditelj).
ki nam ob uporabi prikaže
?- daj_roditelja. cigavega roditelja zelis? leo. roditelj od leo je lili yes
- ponavljanju write se lahko izognemo z
izpisi_sez([]).
izpisi_sez([Glava|Rep]):-
write(Glava),
izpisi_sez(Rep).
daj_roditelja :-
write('cigavega roditelja zelis?),
read(Otrok),
roditelj(Roditelj,Otrok),
izpisi_sez(['roditelj od ',Otrok,' je ',Roditelj]).
- Consultaj samo procedure, ki ustrezajo Predikat/2
consult_proc(Predikat/2,Datoteka):-
see(Dat),
repeat, <--------
read(Stavek), %preberi en stavek
(Stavek = end_of_file, %če je konec dat
seen; %jo zapremo
preveri(Stavek,Predikat/M),
assertz(Stavek), %stavek dodamo na konec
fail). %nazaj k "repeat" ---------^
preveri če je stavek iz željene procedure
preveri(Stavek,P/M) :- (Stavek = (Glava :- _ ),!; %stavek je pravilo Stavek = Glava), %stavek je dejstvo functor(Glava,P,M).
če želimo odstraniti vsa dejstva in pravila preden jih dodamo (da jih ne dupliciramo), moramo uporabiti reconsult:
odstrani(Proc/M) :- functor(Glava,Proc,M), (retract(Glava), fail; %odstrani vsa dejstva retract((Glava :- _)), fail; %odstrani pravila true).
reconsult_proc(Predikat(M,Dat):- odstarani(Predikat/M), consult_proc(Predikat/M,Dat).