```(* Construiti multimea {(1, f(e_1)), ..., (n, f(e_n))}
primind f si multimea {e_1,...,e_n} *)

module S = Set.Make(String)        (* multimea initiala va fi de siruri *)
module IntString = struct        (* rezultatul: multime de perechi int*string *)
type t = int * string                (* f va fi o functie de la sir la sir *)
let compare = compare
end
module PS = Set.Make(IntString)

(* ceva mai simplu, S.map, { f e1, f e2, ..., f en } *)
let setmap f set = S.fold (fun e acc -> S.add (f e) acc) set S.empty

(* acumulatorul e o pereche: contorul curent si multimea construita *)
let setpairmap f set = S.fold (fun e (cnt, mult) ->
(cnt+1, PS.add (cnt, f e) mult)) set (1, PS.empty) |> snd
(* la final selectam doar multimea *)

let test = setpairmap (fun s -> "~" ^ s) mult |> PS.elements

(***************************************************************************)

(* Scrieti o functie care simplifică tiparele A /\ (A \/ B)
dintr-o formulă scrisă cu And|Or|Neg *)

type bform = V of string | Neg of bform | And of bform * bform | Or of bform * bform

let rec simp = function
| Neg e -> Neg (simp e)        (* nu avem ce simplifica aici, doar în jos *)
| And (e1, e2) -> (match (simp e1, simp e2) with        (* cautam la revenire, un Or sub And *)
| (Or(e1, e2), a) | (a, Or(e1, e2)) as p -> (* p e perechea in ambele cazuri *)
if e1 = a || e2 = a then a        (* simplifica *)
else And (fst p, snd p)        (* ramane asa cum e *)
| (e1, e2) -> And (e1, e2))(* orice altceva ramane *)
| Or (e1, e2) -> Or (simp e1, simp e2)        (* nu avem ce simplifica aici, doar în jos *)
| v -> v        (* orice altceva: V _ *)

let form = And (And (V "p", Or (V "p", V "q")), Or (V "p", V "r"))
let test = simp form        (* va simplifica de doua ori *)

```

This document was generated using caml2html