Gestionarea domeniilor unor functii

From HaskellWiki

Problema reprezentarii domeniilor:Atunci cand definim o functie ca cea de mai jos Haskell pare sa nu stie...

f 0 = 1
f 1 = 2   
f 2 = 3

...care este domeniul lui f sau ca s-au terminat ecuatiile si nu are rost sa caute o ecuatie f 3 = ...

Iar ca programator as dori sa intreb daca un argument apartine domeniului unei functii. Cum sa procedez ??

Raspunsul: De fapt Haskell poate sa reprezinte functii impreuna cu informatii despre domeniul lor daca i se spune:
- cum sa le reprezinte
- cum sa prelucreze acele informatii despre domeniile lor

Neplacerea este ca depinzand de aplicatie si de ceea ce doriti de la acele domenii de functii reprezentarea si testarea anumitor proprietati (pentru functiile cu care operati) ar putea sa difere.

1) O prima solutie banala ar fi sa pastrati pe o lista perechile punct-valoare sau punct expresie. Poate fi si un vector. Dezavantaj: functia poate fi definita doar intr-un numar finit de puncte. Sa incercam altceva:

2) Iat o alta idee, inspirata de felul cum erau scrise prima oara ecuatiile acelea:

FUNCTIA este o colectie (lista sau vector sau orice altceva ce se poate parcurge, enumera) de Predicate a -> Bool insotita de - O colectie de FUNCTII care dau valorile functiei ce-o definim corespunzatoare indeplinirii predicatelor - Cele doua colectii sunt ambele enumerabile si au acelasi cardinal. - Exista niste functii simple date prin expresii.



 

type Predicat a = a -> Bool
type Expresie a b = a -> b

data Function a  b = Lista [(Predicat a, Function a b)]
                   | Simpla (Expresie a b )

value (Simpla exp ) a'             = exp a'
value (Lista [] )  a'              = error "Functie nedefinita "
value (Lista ((p,f):perechi)  ) a' = if p a' then  value f a'
                                       else  {- caut mai departe -} 
                                          value (Lista perechi) a' 


indomain (Lista lpfs) a = or (map ($ a) (map fst lpfs) )  --regula 1
indomain (Simpla f) a   = not ( f a /= f a )

Regula 1 face lista predicatelor (map fst lpfs), le transmite tuturor argumentul a prin map ($ a) [....] apoi elementelor Bool-eene obtinute le aplica operatia logica or

Ultima ecuatie n-ar trebui scrisa. ;) daca te intereseaza domeniul unei functii simple si vrei sa-l specifici pune-i ca garda un predicat adevarat pe acel domeniu. Si atunci nu mai este o Simpla, deci se poate aplica regula 1 si nu e nevoie de a doua regula / ecuatie.


Exemplu:


f    = Lista [ (  (0==) , Simpla (+1)          ) ,
               (  (1==) , Simpla (\x -> 2 * x) )  ]

Bineinteles ca in perechi pot fi si functii care nu-s simple.


Functia descrisa de mai sus este o banala functie cu acolada care indeplinea:

f (x) = x + 1 pentru x = 0
f (x) = 2 * x pentru x = 1


Asa cum am reprezentat-o noi aici, functia "stie" ca are 2 predicate (le poti numar pe lista) si poti testa oricand daca un argument apartine dopmeniului, verificand daca exista un prim predicat care devine adevarat pentru acea valoare. Corectitudinea specificarii predicatelor si domeniilor cade in seama programatorului (deocamdata).

Avantaje: De data aceasta domeniul e o multime de predicate deci poate fi si un subdomeniu dintr-un continu ca R.


Sa vedem cum ar mnerge programul: functiicupredicate.hs

 
Main> value f 0
1
Main> value f 3

Program error: Functie nedefinita

Iata si functia indomain care verifica daca un argument apartine domeniului unei functii. N-o aplicati pentru functiile simple inainte de a le garda cu predicatele dumneavoastra.

Main> indomain (Simpla (\x -> 2 / x) ) 0

Program error: {primDivDouble 2.0 0.0}

Main> indomain (Simpla (\x -> 2 / x) ) 1
True
Main> indomain f 0
True
Main> indomain f 1
True
Main> indomain f 2
False
Main>

Iti multumesc C.B., oriunde te-ai afla, pentru problema de mai sus. Aici este doar o varianta a ei. Dan P.

Pagina indexata la indexul Categories:Ro


<= Inapoi la pagina principala Ro/Haskell.

<- Inapoi la Intrebarile incepatorului Ro/Haskell.