Нечеткие множества:
## Код:
```
MODULE FuzzySets;

   (**îïèñàíèå òèïîâ íå÷åòêèõ ìíîæåñòâ**)
   
      TYPE
         (**àáñòðàêòíîå íå÷åòêîå ìíîæåñòâî**)
         FuzzySet* = ABSTRACT RECORD END;
      
         (**òðåóãîëüíîå íå÷åòêîå ìíîæåñòâî**)
         Triangle* = RECORD(FuzzySet)
            a, b, c: REAL
         END;
      
         (**òðàïåöèèäàëüíîå íå÷åòêîå ìíîæåñòâî**)
         Trapezoid* = RECORD(FuzzySet)
            a, b, c, d: REAL
         END;

         (**äðóãèå âèäû íå÷åòêèõ ìíîæåñòâ ìîãóò áûòü îïðåäåëåíû â ñëåäóþùèõ âåðñèÿõ                ìîäóëÿ**)
         
         
   (**îïðåäåëåíèå ôóíêöèé ïðèíàäëåæíîñòè íå÷åòêèõ ìíîæåñòâ**)   
   
   (**àáñòðàêòíàÿ ôóíêöèÿ ïðèíàäëåæíîñòè**)
   PROCEDURE (VAR fs: FuzzySet) MF* (x: REAL): REAL, NEW, ABSTRACT;
   
   (**ôóíêöèÿ ïðèíàäëåæíîñòè òðåóãîëüíîãî íå÷åòêîãî ìíîæåñòâà**)
   PROCEDURE (VAR tri: Triangle) MF* (x: REAL): REAL;
   BEGIN
      (*òðåóãîëüíèê ìîæåò âûðîæäàòüñÿ â ëèíèþ*)
      IF (tri.a = tri.b) & (tri.b = tri.c) THEN 
         IF (x = tri.a) THEN RETURN 1 ELSE RETURN 0 END
      END;
      IF (tri.a = tri.b) THEN
         IF (tri.b <= x) & (x <= tri.c) THEN
            RETURN ((tri.c - x) / (tri.c - tri.b))
         ELSE
            RETURN 0
         END
      END;
      IF (tri.b = tri.c) THEN
         IF (tri.a <= x) & (x <= tri.b) THEN
            RETURN ((x - tri.a) / (tri.b - tri.a))
         ELSE
            RETURN 0
         END
      END;      
      RETURN MAX(MIN((x - tri.a) / (tri.b - tri.a), (tri.c - x) / (tri.c - tri.b)), 0)
   END MF;
   
   (**ôóíêöèÿ ïðèíàäëåæíîñòè òðàïåöèèäàëüíîãî íå÷åòêîãî ìíîæåñòâà**)
   PROCEDURE (VAR trap: Trapezoid) MF* (x: REAL): REAL;
      VAR y1, y2: REAL;
   BEGIN
      y1 := 0; y2 := 0;
      (*òðàïåöèÿ ìîæåò âûðîæäàòüñÿ â òðåóãîëüíèê*)
      IF (trap.b <= x) THEN
         y1 := 1
      ELSIF (x < trap.a) THEN
         y1 := 0
      ELSIF (trap.a # trap.b) THEN
         y1 := (x - trap.a) / (trap.b - trap.a)
      END;
      IF (x <= trap.c) THEN
         y2 := 1
      ELSIF (trap.d < x) THEN
         y2 := 0
      ELSIF (trap.c # trap.d) THEN
         y2 := (trap.d - x) / (trap.d - trap.c)
      END;
      RETURN MIN(y1, y2)
   END MF;    
   
   
   (**îïðåäåëåíèå ôóíêöèé èíèöèàëèçàöèè íå÷åòêèõ ìíîæåñòâ**)
   
   (**óñòàíîâêà ïàðàìåòðîâ òðåóãîëüíîãî íå÷åòêîãî ìíîæåñòâà**)
   PROCEDURE (VAR tri: Triangle) SetParams* (a, b, c: REAL), NEW;
   BEGIN
      ASSERT(~(a > b) & ~(b > c));
      tri.a := a; tri.b := b; tri.c := c
   END SetParams;
   
   (**óñòàíîâêà ïàðàìåòðîâ òðàïåöèèäàëüíîãî íå÷åòêîãî ìíîæåñòâà**)
   PROCEDURE (VAR trap: Trapezoid) SetParams* (a, b, c, d: REAL), NEW;
   BEGIN
      ASSERT(~(a > b) & ~(b > c) & ~(c > d));
      trap.a := a; trap.b := b; trap.c := c; trap.d := d
   END SetParams;
   
   (**äèíàìè÷åñêîå ðàçìåùåíèå òðåóãîëüíîãî íå÷åòêîãî ìíîæåñòâà**)
   PROCEDURE NewTriangle* (a, b, c: REAL): POINTER TO FuzzySet;
      VAR tri: POINTER TO Triangle;
   BEGIN
      NEW(tri);
      tri.SetParams(a, b, c);
      RETURN tri
   END NewTriangle;
   
   (**äèíàìè÷åñêîå ðàçìåùåíèå òðàïåöèèäàëüíîãî íå÷åòêîãî ìíîæåñòâà**)
   PROCEDURE NewTrapezoid* (a, b, c, d: REAL): POINTER TO FuzzySet;
      VAR trap: POINTER TO Trapezoid;
   BEGIN
      NEW(trap);
      trap.SetParams(a, b, c, d);
      RETURN trap
   END NewTrapezoid;


   (**îïåðàöèè íàä íå÷åòêèìè ìíîæåñòâàìè**)
   
   (*ïåðåñå÷åíèå*)
   PROCEDURE Crossing* (IN Lset, Rset: FuzzySet; x: REAL): REAL;
   BEGIN
      RETURN  MIN(Lset.MF(x), Rset.MF(x));
   END Crossing;   
      
   (*îáúåäèíåíèå*)
   PROCEDURE Association* (IN Lset, Rset: FuzzySet; x: REAL): REAL;
   BEGIN
      RETURN  MAX(Lset.MF(x), Rset.MF(x));
   END Association;
   
   (*äîïîëíåíèå*)
   PROCEDURE Not* (IN set: FuzzySet; x: REAL): REAL;
   BEGIN
      RETURN (1 - set.MF(x));
   END Not;
   
END FuzzySets.
```
