Linguaggio didattico per la teoria degli insiemi
SETL (SET Language) è stato sviluppato da Jacob T. Schwartz negli anni 1969-70 presso il Courant Institute. In seguito Gary Levin sviluppò ISETL (Interactive SET Language), per un utilizzo interattivo in ambienti Unix, DOS, e Macintosh alla Clarkson University. La versione per Windows, ISETLW, è dovuta a John Kirchmeyer del Mount Union College con l’aiuto di Jamie Wylie nel 1995, nel 2001 è disponibile la versione 3, sempre ad opera di John Kirchmeyer.
SETL è un linguaggio di programmazione indirizzato alla teoria degli insiemi, infatti oltre ai tipi elementari di dato, stringhe di caratteri, numeri interi illimitati, numeri reali, booleani, prevede:
· tuple, liste di oggetti qualsivoglia, le tuple sono racchiuse da [],
· set, insiemi di oggetti qualsivoglia ma non duplicati, gli insiemi sono racchiusi fra {},
·
map, insiemi di 2-tuple, con il
primo componente funzionante come una chiave.
Una variabile non
inizializzata ha il tipo di dato OM (omega).
Per l’utilizzo degli insiemi
sono disponibili:
· operazioni di unione, intersezione e differenza tramite gli operatori + o union, * o inter e – rispettivamente.
· Costruttori (formers), peraltro utilizzati anche per le tuple e per le istruzioni di iterazione.
· Funzioni di test: in, notin e subset.
· Funzioni di estrazione e quantificazione: take ... from, choose, arb, forall ed exist.
· Costruzione tramite condizione introdotta dai simboli, equivalenti, : o |, col significato di "tale che".
primo
:= func(n);
ins := {p | p
in {n} |(forall indx in {2.. p div 2}| p mod
indx /= 0)};
if #ins = 1 then
return "primo"
else
return "non primo";
end if; end
func; numeri
:= {}; $ insieme vuoto for indx in [3..50] do
numeri
:= numeri union {[primo(indx),indx]};
$ insieme mappa end for; > numeri{"primo"}; {17,
13, 3, 5, 11, 7, 23, 19, 31, 29, 43, 47, 37, 41}; >
arb(numeri); $ estrazione di un elenco arbitrario ["non primo", 38];
|
I selettori sono uno strumento efficace per trattare stringhe, tuple ed insiemi, hanno la forma n..m, dove n o m possono mancare:
> stringa := "lafleur";
>
stringa(..3); $ left 3 "laf"; >
stringa(#stringa-2..); $ right 3 "eur";
|
E’ possibile scrivere ed utilizzare librerie di moduli, la versione per Windows è fornita con funzioni per grafica vettoriale.
SETL ha aspetti funzionali, la definizione di un insieme, produce l’insieme:
> {[a,b,c] : a,b,c in [1..20] | a < b and a**2 + b**2 =c**2};
{[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [12, 16, 20], [9, 12, 15]};
|
L’esempio che segue è una simulazione dell’evoluzione di una popolazione, rappresentata da numeri fra 0 e 255, tramite un’algoritmo genetico (embrionale). Gli individui con un particolare gene, per semplicità è il bit che rende il numero dispari, soccombono in maggior misura degli altri.
$ ISETLW ISETL for Windows Version 3.0 Beta 0
$ genpop generate n different peoples genpop := func(x,n); while #x < n do
x
:= x + {random({0..255})};
end while; return x end; $ newpop generate a new individual, from two individual (mf is twople
of eightple) newpop := func(mf); new := 0; for bit in {1..8} do new
:= new + mf(arb([1,2]))(bit) * 2 **(bit-1) end for; return new end; $ extpop extract n peoples extpop := func(x,n); extract := {}; while #extract < n do extract
:= extract + {arb(x)}; end while; return extract end; $ tobit transform number in bits tobit := func(n); bits
:= [0,0,0,0,0,0,0,0]; for
i in [1..8] do
bits(i) := n mod 2;
n
:= n div 2;
end; return
bits; end; genetica := func(); print "Genetic Algorithm Simulation"; randomize(arb({1..100})); sost := 0.2;
$ % of sostitution people sostodd := 0.6; $ % of
sostitution odd people npop := 100;
$ population number $ generation of initial population pop := {}; pop := genpop(pop,npop); writeln "generation odd people even people restored"; for indx in [1..15] do $
extract a subset of discarded population oddelim
:= extpop({op |op in pop | op mod 2 /= 0},floor(npop*sost*sostodd)); evenelim
:= extpop({op |op in pop | op mod 2 = 0},floor(npop*sost*(1-sostodd))); pop
:= pop-oddelim-evenelim; for
cnt in [1..npop-#pop] do
$ regenerate peoples
pop := pop + {newpop([tobit(arb(pop)),tobit(arb(pop))])}; end; writeln
indx,#{op |op in pop | op mod 2 /= 0}, #{op |op in pop | op mod 2 = 0},npop
- #pop; $writeln
"restore",npop - #pop," peoples"; pop
:= genpop(pop,npop);
$ restore total polpulation (mutation) $write
"even people:", #{op |op in pop | op mod 2 = 0}; $writeln
" odd people:",#{op |op in pop | op mod 2 /= 0}; end; end; genetica();
|
"Genetic Algorithm Simulation"; generation odd people even people restored
1
45 43
12
2
43 46
11
3
41 51
8
4
37 52
11
5
34 54
12
6
35 55
10
7
36 52
12
8
34 55
11
9
32 59
9
10
29 59 12
11
23 65
12
12
20 68
12
13
18 70
12
14
21 66
13
15
19 70
11
|