Lucrarea nr. 7

Cuprins:

  1. Operatori
  2. Predicate de intrare / iesire

1. Operatori




In SWI-Prolog exista urmatorii operatori predefiniti:
 
Prioritate
Tip
Operatori
1200 xfx  -->, :-
1200 fx  :-, ?-
1150 fx dynamic, multifile, module_transparent, discontiguous, volatile,initialization
1100 xfy ;, |
1050 xfy ->
1000 xfy  ,
954 xfy \
900 fy  \+, not
900 fx ~
700 xfx <, =, =.., =@=, =:=, =<, ==, =\=, >, >, =, @<, @=<, @>, @>=, \=, \==, is
600 xfy :
500 yfx +, -, /\, \/, xor
500 fx +, -, ?, \
400 yfx *, /, //, <<, >>, mod, rem
200 xfx **
200 xfy  ^

Tipul unui operator specifica atat clasa (infix, prefix sau postfix), cat si asociativitatea. Cea din urma determina ce se intampla daca sunt doi operatori de aceeasi prioritate in ambele parti ale unui argument. De exemplu, in '2+3+4', 3 ar putea fi adunat prima data cu 2 sau cu 4. Asociativitatea 'yfx' specifica faptul ca '2+3+4' este echivalent cu '(2+3)+4'.

Programatorul poate sa-si defineasca proprii sai operatori cu ajutorul directivei 'op'. De exemplu, operatorul de negatie (\+) este definit prin:

    :- op(900, fy, \+).

Noi functii aritmetice se pot adauga prin directiva 'arithmetic_function', prin care se specifica numele si aritatea functiei. Functia, la rindul sau, va fi definita ca si un predicat care are ca ultim argument valoarea returnata de functie.

    :- arithmetic_function(mean/2).
    mean(A, B, C) :- C is (A+B)/2.

Aceste functii pot fi declarate, in plus, si ca operatori:

    :- op(550,xfx,mean).

Definirea operatorilor nu este constransa la predicate sau functii, aceasta fiind posibila pentru orice functor pe care vrem sa-l utilizam. Singura restrictia este ca termenul al carui functor este operatorul definit sa aiba cel mult doi parametri.

Probleme:

  1. Consideram operatorii 'plays' si 'and' definiti prin

        :- op(300,xfx,plays).
        :- op(200,xfy,and).

    Care este structura functoriala a termenului

        Term = jimmy plays football and basketball and tennis.

    Propuneti o definitie pentru operatorii 'was', 'of' si 'the', care ne permite sa scriem clauze de forma:

  2.     john was the secretary of the department.

    dupa care sa putem pune intrebari de genul:

        ?- Who was the secretary of the department.
     

  3. Sa se defineasca operatorii 'in', 'deleting', 'from' etc. astfel incat sa putem scrie:

        Element in List.
        deleting Element from List gives NewList.
        concatenating List1 and List2 ... and ListN gives NewList.

    Redefiniti predicatele necesare, daca este nevoie.
     


2. Predicate de intrare/iesire





In Prolog un fisier poate fi deschis cu 'open':

    open(SrcDest, Mode, Stream)

unde

Exemplu:

    reads(Stream,[Char | String]) :-
        get(Stream,Char), Char \== -1, !,reads(Stream, String).
    reads(_,[]).

    get_pwd(Pwd) :- open(pipe(pwd),read,F), reads(F,S),atom_chars(Pwd,S).

Fisierul deschis poate fi inchis prin 'close(Stream)'. Pe langa fisierele deschise cu open, mai exista trei fisiere speciale: user_input, user_output si user_error.
Toate predicatele descrise in continuare care au ca prim argument un identificator de fisier (Stream) au si o forma fara acest argument, caz in care predicatul se refera la user_I/O.
 

Predicate la nivel de caracter

put(Stream,Char)
    scrie caracterul Char

nl(Stream)
    scrie caracterul \n

get(Stream,Char)
    citeste primul caracter non-blank si unifica cu Char; la sfirsit de fisier unifica Char cu -1

get0(Stream,Char)
    citeste primul caracter si unifica cu Char

 Exemplu:
    reads(Stream,[Char | String]) :-
        get(Stream,Char), Char \== -1, !,reads(Stream, String).
    reads(_,[]).
    get_pwd(Pwd) :-
        open(pipe(pwd),read,Handle),
        reads(Handle,S),atom_chars(Pwd,S).
 

Predicatele care opereaza cu termeni Prolog

write(Stream,Term)
    scrie termenul Term

writeq(Stream,Term)
    ca si write, dar pune '' in jurul atomilor care contin in interior separatori ('ca acesta')

read(Stream,Term)
    citeste termenul Term; termenul trebuie sa fie terminat cu '.'; la sfirsit de fisier unifica Term cu 'end_of_file'
 
 

Scriere cu format

writef(+Format, +Arguments)
    Format este un atom care poate contine urmatoarele simboluri speciale care se refera la argumente. Cele mai importante sunt:
        %w  scrie urmatorul argument folosind write
        %q  scrie urmatorul argument folosind writeq
        %n  scrie urmatorul argument ca si caracter
        %s  scrie urmatorul argument ca si string

swritef(String, Format, Arguments)
    ca si writef, dar "scrie" in varibila String

 Exemplu:
    ?- writef('%s %s!\n', ["Hello", "world"]).
    Hello world!
 
 

Probleme:

  1. Sa se defineasca un predicat care citeste in mod repetat un numar, afisand patratul acestuia. Predicatul se termina daca utilizatorul introduce atomul stop.
  2. Sa se defineasca un predicat care afiseaza o lista in forma:
    ?- writelist([1,2,3]).
    1 2 3