1 Meccanismi per la definizione di tipi di dato §la programmazione di applicazioni consiste in gran parte nella definizione di nuovi tipi di dato §un qualunque.

Slides:



Advertisements
Presentazioni simili
TAV.1 Foto n.1 Foto n.2 SCALINATA DI ACCESSO ALL’EREMO DI SANTA CATERINA DEL SASSO DALLA CORTE DELLE CASCINE DEL QUIQUIO Foto n.3 Foto n.4.
Advertisements

1 Le s-espressioni. 2 Un nuovo esempio completo: le s-espressioni Sexpr 4 alberi binari (possibilmente vuoti) che hanno sulle foglie atomi (stringhe)
1 Progettazione gerarchica delle s- espressioni, utilizzando lereditarietà
Modello dati LISTA LISTA: LISTA: sequenza finita di 0 o più elementi LISTA di tipo T: lista in cui tutti gli elementi sono dello stesso tipo T. es. lista.
Interfacce Java.
1 Processi e Thread Processi Thread Meccanismi di comunicazione fra processi (IPC) Problemi classici di IPC Scheduling Processi e thread in Unix Processi.
1 Semantica Operazionale di un frammento di Java: lo stato.
Esercizio 2. Mostrare l'evoluzione dello stato (ambiente di classi, heap, pila, System.out) durante la valutazione delle seguenti dichiarazioni di classe.
Sequential Statements. – Il VHDL simula lo svolgersi in parallelo di varie operazioni – Loggetto fondamentale e il PROCESS – Un PROCESS contiene una serie.
Frontespizio Economia Monetaria Anno Accademico
Programmazione Parametrica ( a.k.a. Generics )
Programmazione Parametrica ( a.k.a. Generics ). Introduzione ai meccanismi e concetti della programmazione parametrica Generics e relationi di sottotipo.
EJB Enterprise Java Beans B. Pernici. Approccio Java.
Tail recursion: esempio
Model – View - Controller
Esempio: Tombola! Parte seconda.
Unified Modeling Language class C {…} class B extends C {…} Esiste una notazione grafica per mostrare le relazioni di ereditarietà. Object StringC B Tutte.
Richiami di Java Multithreading. Threads (subclassing) public class A { public void a_method { C t = new C(); //C t = new C(String name); t.start(); …
Sezione: Costruttori Costruttori. Definizione dei costruttori Se per una classe A non scrivo nessun costruttore, il sistema automaticamente crea il costruttore.
prompt> java SumAverage
1 struct Pila { private: int size; int defaultGrowthSize; int marker; int * contenuto; void cresci(int increment); public: Pila(int initialSize) ; Pila();
HDM Information Design notation v.4. HDM Information Design.
Ufficio Studi UNIONCAMERE TOSCANA 1 Presentazione di Riccardo Perugi Ufficio Studi UNIONCAMERE TOSCANA Firenze, 19 dicembre 2000.
eliana minicozzi linguaggi1a.a lezione2
Sviluppo di Software Sicuro - S 3 SPARK – Moduli Corso di Laurea Magistrale in Sicurezza Informatica: Infrastrutture e Applicazioni Università di Pisa.
1 Ultima Lezione del Corso di Fondamenti di Informatica 1 a.a – 06 Ma 29-Nov-2005.
1. Conoscere luso delle collezioni in Java Comprendere le principali caratteristiche nelle varie classi di Collection disponibili Saper individuare quali.
JAVA C import java.util.*; #include <stdio.h>
Il linguaggio Fortran 90: 4. Array: Vettori e Matrici
6.6Ordinamento di Vettori Ordinamento di dati –Applicazione computazionale importante –Virtualmente ogni organizzazione deve ordinare dei dati Enormi quantità
Modello dati LISTA LISTA: LISTA: sequenza finita di 0 o più elementi LISTA di tipo T: lista in cui tutti gli elementi sono dello stesso tipo T. es. lista.
1 Implementazione di Linguaggi 2 PARTE 6 Implementazione di Linguaggi 2 PARTE 6 Massimo Ancona DISI Università di Genova Testo: A.V. Aho, R. Sethi, J.D.Ullman.
2000 Prentice Hall, Inc. All rights reserved. 1 Capitolo 6: Classi e astrazione dati 1.Introduzione 2.Definizione delle strutture 3.Accedere ai membri.
Sottoprogrammi e Unità di Compilazione Nicola Fanizzi Laboratorio - Corso di Programmazione (B) C.d.L. in Informatica DIB - Università degli Studi di Bari.
Array Ricerca Ordinamento Fusione Nicola Fanizzi Laboratorio - Corso di Programmazione (B) C.d.L. in Informatica DIB - Università degli Studi di Bari.
FONDAMENTI DI INFORMATICA III WfMC-1. FONDAMENTI DI INFORMATICA III WfMC-2 WFMC Cose WfMC Workflow Management Coalition (WfMC), Brussels, è unorganizzazione.
Constraints.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Ricerca di una chiave: Search(x, k) if x == nil or k == x.key return x
2 3 4 RISERVATEZZA INTEGRITA DISPONIBILITA 5 6.
22 maggio 2002 Avvisi: Ultima lezione: mercoledì 29 maggio II Esonero: mercoledì 5 giugno, ore 10:00.
Un esempio: Registrazione e lettura di dati in un file
JavaScript Lezione 5 Tipizzazione ed operazioni tra tipi diversi Istruzioni di input.
OUTPUT FORMATTATO La funzione printf consente di effettuare la stampa a video formattata. Sintassi: printf ( stringa_formato, arg0, arg1, … ); La stringa.
Moduli o Form I Moduli permettono all'utente di immettere informazioni...
Fondamenti di Informatica Corsi di Laurea in Ingegneria Gestionale Canale AL ESERCITAZIONE 6 ARGOMENTI: LAVORARE CON CLASSI METODI DELLISTANZA, COSTRUTTORI.
1 Negozi Nuove idee realizzate per. 2 Negozi 3 4.
1 Guida per linsegnamento nei corsi per il conseguimento del CERTIFICATO DI IDONEITÀ ALLA GUIDA DEL CICLOMOTORE.
Bando Arti Sceniche. Per poter procedere è indispensabile aprire il testo del Bando 2ROL - Richieste On Line.
Realizzazione Grammatica non contestuale –no ricorsioni sinistre –LL(1) produzione individuata dal primo token Ogni non-terminale -> funzione –rappresenta.
24 aprile 2002 Avvisi: Risultati 1 o Esonero: (entro) lunedi 27 disponibili nella pag. WEB, ma anche esposti nella bacheca fuori dal corridoio 2 o dente,
Ese 2 (del 31 Marzo 2004). Mostrare l'evoluzione dello stato (ambiente di classi, heap, pila, System.out) durante la valutazione delle seguenti dichiarazioni.
Multiset. Progettare (specifica con identificazione delle eventuali astrazioni necessarie, incluse eccezioni, e implementazione) del tipo di dato Multiset,
Test con JUnit. zJUnit è un ambiente di test per programmi Java ySviluppato da Kent Beck É possibile usare JUnit allinterno di Eclipse per eseguire i.
1 Simulated multiple inheritance Sandro Pedrazzini Approfondimento Simulated multiple inheritance in Java.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
Introduzione al linguaggio C. Cos’e’ il C? Il C e’ un linguaggio ad alto livello Un compilatore C prende in input un file contenente codice sorgente C.
Collection & Generics in Java
Fondamenti di informatica T-A Esercitazione 7 : Collezioni AA 2012/2013 Tutor : Domenico Di Carlo.
JDBC Java DataBase Connectivity SISTEMI ITIS B. CASTELLI Anno Scolastico
1 Implementazione degli oggetti. 2 Contenuti ¥effetto dell’implementazione di ambiente e memoria sugli oggetti ¥ oggetti come ambiente e memoria permanente.
IL GIOCO DEL PORTIERE CASISTICA. Caso n. 1 Il portiere nella seguente azione NON commette infrazioni.
1 Tipi di Dato §descrittori, tipi, controllo e inferenza dei tipi §specifica (semantica) e implementazione di tipi di dato l implementazioni “sequenziali”
Algoritmi e Strutture Dati Strutture Dati Elementari.
1 Controllo di sequenza: espressioni e comandi. 2 Contenuti ¥espressioni pure (senza blocchi e funzioni) ¥ regola di valutazione, operazioni strette e.
1 Tipi di Dato §descrittori, tipi, controllo e inferenza dei tipi §specifica (semantica) e implementazione di tipi di dato l implementazioni “sequenziali”
1 Programmazione Funzionale: ML 1 implementazione del -calcolo tipato l definizione di nuovi tipi ricorsivi l i valori dei nuovi tipi sono termini, che.
1 Tipi di dato modificabili §a livello semantico, riconduciamo la modificabilità alla nozione di variabile l lo stato “modificabile” corrispondente sarà.
.  I tipi di dati non primitivi sono gli array, le struct e le union.  Gli array sono degli aggregati di variabili dello stesso tipo.  La dichiarazione.
APPUNTI SUL LINGUAGGIO C
Transcript della presentazione:

1 Meccanismi per la definizione di tipi di dato §la programmazione di applicazioni consiste in gran parte nella definizione di nuovi tipi di dato §un qualunque tipo di dato può essere definito in qualunque linguaggio l anche in linguaggio macchina §gli aspetti importanti l quanto costa? l esiste il tipo? l il tipo è astratto?

2 Quanto costa? 1 §il costo della simulazione di un nuovo tipo di dato dipende dal repertorio di strutture dati primitive fornite dal linguaggio l in linguaggio macchina, le sequenze di celle di memoria l in FORTRAN e ALGOL60, gli arrays l in PASCAL e C, le strutture allocate dinamicamente ed i puntatori l in LISP, le s-espressioni l in ML e Prolog, le liste ed i termini l in C ++ e Java, gli oggetti

3 Esiste il tipo? §anche se abbiamo realizzato una implementazione delle liste (con heap, lista libera, etc.) in FORTRAN o ALGOL l non abbiamo veramente a disposizione il tipo §poichè i tipi non sono denotabili l non possiamo dichiarare oggetti di tipo lista §stessa situazione in LISP e Prolog §in PASCAL, ML, Java i tipi sono denotabili, anche se con meccanismi diversi l dichiarazioni di tipo l dichiarazioni di classe

4 Dichiarazioni di tipo type nometipo = espressione di tipo §il meccanismo di PASCAL, C ed ML §il potere espressivo dipende dai meccanismi forniti per costruire espressioni di tipo (costruttori di tipo) l PASCAL, C enumerazione record, record ricorsivo l ML enumerazione prodotto cartesiano iterazione somma funzioni ricorsione §ci possono essere tipi parametrici l in particolare, polimorfi (parametri di tipo tipo)

5 Linguaggi Object-Oriented §il meccanismo di C ++ e Java (anche OCAML) §il tipo è la classe l parametrico in OCAML l con relazioni di sottotipo §i valori del nuovo tipo (oggetti) sono creati con unoperazione di istanziazione della classe l non con una dichiarazione §la parte struttura dati degli oggetti è costituita da un insieme di variabili istanza (o fields) allocati sulla heap §Le operazioni associate sono definite da metodi distanza

6 Il tipo è astratto? §un tipo astratto (TDA) è un insieme di valori l di cui non si conosce la rappresentazione (implementazione) l che possono essere manipolati solo con le operazioni associate §sono tipi astratti tutti i tipi primitivi forniti dal linguaggio l la loro rappresentazione effettiva non ci è nota e non è comunque accessibile se non con le operazioni primitive §per realizzare tipi di dato astratti servono l un meccanismo che permette di dare un nome al nuovo tipo (dichiarazione di tipo o di classe) l un meccanismo di protezione o information hiding che renda la rappresentazione visibile soltanto alle operazioni primitive

Linguaggi Moderni: TDA §I programmi possono essere organizzati in moduli separati, la cui implementazione e invisibile al resto del programma § limplementazione dei moduli puo essere moficata-aggiornata senza modificare il resto del programma

Correttezza e Proprieta §E possibile garantire in modo semplice proprieta invarianti del tipo di dato (il codice esterno non puo accedere allimplementazione) § Esempio: Btree ordinato

9 Come si realizzano? §In Java un tipo di dato astratto si realizza utilizzando classi o interfacce, e usando per la rappresentazione variabili istanza private §In OCAML moduli e interfacce interfaccia (signature) dichiara il tipo, la parte accessibile (strutture dati e metodi) implementazione e definita in un file separato (e invisibile)

OCAML §Classi, oggetti, ereditarieta : brevemente le differenze piu rilevanti §Moduli ed Interfacce

11 Classi e oggetti # class point x_init = object val mutable x = x_init method get_x = x method move d = x <- x + d end;; class point : int -> object val mutable x : int method get_x : int method move : int -> unit end # let p = new point (3);; val p : point = # p#get_x;; - : int = 3 # p#move 33;; - : unit = () # p#get_x;; - : int = 36

Ereditarietà class point : int -> object val mutable x : int method get_x : int method move : int -> unit end # class colored_point x (c : string) = object inherit point x val c = c method color = c end;; class colored_point : int -> string -> object val c : string val mutable x : int method color : string method get_x : int method move : int -> unit end # let p' = new colored_point 5 "red";; val p' : colored_point = # p'#color;; - : string = "red"

Moduli ed Interfacce §per supportare in modo semplice i concetti di encapsulation e data hiding §linterfaccia e definita da una module signature (.mli) §limplementazione (o le) e definita da una module structure (.ml)

Signature: interfaccia §dichiara il tipo §dichiara i metodi pubblici, tramite la parola chiave val (nome, parametri, tipo)

15 Moduli: interfaccie # module type PILA = sig type 'a stack (* abstract *) val emptystack : 'a stack val push : 'a stack -> 'a -> 'a stack val pop : 'a stack -> 'a stack val top : 'a stack -> 'a end;; module type PILA = sig type 'a stack val emptystack : 'a stack val push : 'a stack -> 'a -> 'a stack val pop : 'a stack -> 'a stack val top : 'a stack -> 'a end

Structure: implementazione §implementa il tipo ed i metodi associati §puo contenere definizioni ausiliarie, da fuori e visibile solo quello che e specificato nella corrispondente interfaccia (signature)

17 Moduli: implementazione # module SpecPila: PILA = struct type 'a stack = Empty | Push of 'a stack * 'a let emptystack = Empty let push p a = Push(p,a) let pop p = match p with | Push(p1, _) -> p1 let top p = match p with | Push(_, a) -> a end;; module SpecPila : PILA

Commenti Il tipo astratto a stack e implementato tramite una definizione ricorsiva §I metodi sono implementati di conseguenza §Limplementazione resta invisibile (in questo caso non ci sono definizioni ausiliarie, rimarrebbero comunque non visibili)

Come si usa un modulo? §Chiamando i metodi con nome-modulo.nome-metodo #let p= ref PILA.emptystack;; #p:=push p prova;;

Applicazione §Useremo il sistema dei moduli per presentare alcuni esempi di TDA rilevanti §Diverse implementazioni, diversi livelli di astrazione (corrispondenti alla stessa structure, interfaccia) §Semantica algebrica, specifica astratta §Implementazione concreta

21 Pila non modificabile: interfaccia # module type PILA = sig type 'a stack val emptystack : int * 'a -> 'a stack val push : 'a * 'a stack -> 'a stack val pop : 'a stack -> 'a stack val top : 'a stack -> 'a val empty : 'a stack -> bool val lungh : 'a stack -> int exception Emptystack exception Fullstack end

Commenti emptystack prende come parametro un intero (la dimensione, il numero massimo di elementi memorizzabili) ed il tipo push, pop, top, empty standard lungh per avere il numero degli elementi, correntemente memorizzati Emptystack,Fullstack eccezioni usate dal modulo

23 Pila non modificabile: semantica # module SemPila: PILA = struct type 'a stack = Empty of int | Push of 'a stack * 'a exception Emptystack exception Fullstack let emptystack (n, x) = Empty(n) let rec max = function | Empty n -> n | Push(p,a) -> max p let rec lungh = function | Empty n -> 0 | Push(p,a) -> 1 + lungh(p) let push (a, p) = if lungh(p) = max(p) then raise Fullstack else Push(p,a) let pop = function | Push(p,a) -> p | Empty n -> raise Emptystack let top = function | Push(p,a) -> a | Empty n -> raise Emptystack let empty = function | Push(p,a) -> false | Empty n -> true end

24 Semantica Algebrica §semantica isomorfa ad una specifica in stile algebrico l trascuriamo i casi eccezionali 'a stack = Empty of int | Push of 'a stack * 'a emptystack (n, x) = Empty(n) lungh(Empty n) = 0 lungh(Push(p,a)) = 1 + lungh(p) push(a,p) = Push(p,a) pop(Push(p,a)) = p top(Push(p,a)) = a empty(Empty n) = true empty(Push(p,a)) = false §tipo (ricorsivo) definito per casi (con costruttori) §semantica delle operazioni definita da un insieme di equazioni fra termini il metodo lungh fornisce il numero di valori memorizzati il metodo max fornisce la dimensione massima (non fa parte dellinterfaccia, non e visibile da fuori)

25 Pila non modificabile: implementazione # module ImpPila: PILA = struct type 'a stack = Pila of ('a array) * int end §La prima componente dellimplementazione è un array §La seconda componente dellimplementazione è un intero, che rappresenta, in ogni istante, lindice fino a cui larray e utilizzato (-1 quando e vuoto) §classica implementazione sequenziale utilizzabile anche per altri tipi di dato simili alle pile (code)

26 Pila non modificabile: implementazione # module ImpPila: PILA = struct type 'a stack = Pila of ('a array) * int exception Emptystack exception Fullstack let emptystack (nm,x) = Pila(Array.create nm x, -1) let push(x, Pila(s,n)) = if n = (Array.length(s) - 1) then raise Fullstack else (Array.set s (n +1) x; Pila(s, n +1)) let top(Pila(s,n)) = if n = -1 then raise Emptystack else Array.get s n let pop(Pila(s,n)) = if n = -1 then raise Emptystack else Pila(s, n -1) let empty(Pila(s,n)) = if n = -1 then true else false let lungh(Pila(s,n)) = n end

27 Lista (non polimorfa): interfaccia # module type LISTAINT = sig type intlist val emptylist : intlist val cons : int * intlist -> intlist val tail : intlist -> intlist val head : intlist -> int val empty : intlist -> bool val length : intlist -> int exception Emptylist end

28 Lista: semantica # module SemListaInt: LISTAINT = struct type intlist = Empty | Cons of int * intlist exception Emptylist let emptylist = Empty let rec length = function | Empty -> 0 | Cons(n,l) -> 1 + length(l) let cons (n, l) = Cons(n, l) let tail = function | Cons(n,l) -> l | Empty -> raise Emptylist let head = function | Cons(n,l) -> n | Empty -> raise Emptylist let empty = function | Cons(n,l) -> false | Empty -> true end

29 Lista e Pila: stessa semantica intlist = Empty | Cons of int * intlist emptylist = Empty length(Empty) = 0 length(Cons(n,l)) = 1 + length(l) cons (n, l) = Cons(n, l) tail(Cons(n,l)) = l head(Cons(n,l)) = n empty(Empty) = true empty(Cons(n,l)) = false 'a stack = Empty of int | Push of 'a stack * 'a emptystack (n, x) = Empty(n) lungh(Empty n) = 0 lungh(Push(p,a)) = 1 + lungh(p) push(a,p) = Push(p,a) pop(Push(p,a)) = p top(Push(p,a)) = a empty(Empty n) = true empty(Push(p,a)) = false

30 Stessa implementazione? §non conviene implementare una lista con un array l vorremmo una implementazione sequenziale in cui un unico array viene utilizzato per rappresentare tante liste la heap! §larray unico va bene per la pila perché è un tipo di dato di sistema ne esistono un numero piccolo e predefinito nella implementazione del linguaggio §la lista è tipicamente un tipo di dato dutente l che ne può costruire un numero arbitrario nei propri programmi mostriamo limplementazione delle liste con una heap senza operazioni per disallocare

31 Heap, lista libera, allocazione heads tails next newpoint := next; next := tails[next]; heads[newpoint] := n; tails[newpoint] := l; newpoint cons(n, l)

32 Lista: implementazione a heap # module ImpListaInt: LISTAINT = struct type intlist = int let heapsize = 100 let heads = Array.create heapsize 0 let tails = Array.create heapsize 0 let next = ref(0) let emptyheap = let index = ref(0) in while !index < heapsize do Array.set tails !index (!index + 1); index := !index + 1 done; Array.set tails (heapsize - 1) (-1); next := 0 exception Fullheap exception Emptylist let emptylist = -1 let empty l = if l = -1 then true else false let cons (n, l) = if !next = -1 then raise Fullheap else ( let newpoint = !next in next := Array.get tails !next; Array.set heads newpoint n; Array.set tails newpoint l; newpoint) let tail l = if empty l then raise Emptylist else Array.get tails l let head l = if empty l then raise Emptylist else Array.get heads l let rec length l = if l = -1 then 0 else 1 + length (tail l) end

33 Ambiente (env) §tipo (polimorfo) utilizzato nella semantica e nelle implementazioni per mantenere una associazione fra stringhe (identificatori) e valori di un opportuno tipo §la specifica definisce il tipo come funzione §limplementazione che vedremo utilizza le liste §è simile il dominio store

34 Ambiente: interfaccia # module type ENV = sig type 't env val emptyenv : 't -> 't env val bind : 't env * string * 't -> 't env val bindlist : 't env * (string list) * ('t list) -> 't env val applyenv : 't env * string -> 't exception WrongBindlist end

35 Ambiente: semantica # module Funenv:ENV = struct type 't env = string -> 't exception WrongBindlist let emptyenv(x) = function y -> x let applyenv(x,y) = x y let bind(r, l, e) = function lu -> if lu = l then e else applyenv(r,lu) let rec bindlist(r, il, el) = match (il,el) with | ([],[]) -> r | i::il1, e::el1 -> bindlist (bind(r, i, e), il1, el1) | _ -> raise WrongBindlist end

36 Ambiente: implementazione # module Listenv:ENV = struct type 't env = (string * 't) list exception WrongBindlist let emptyenv(x) = [("",x)] let rec applyenv(x,y) = match x with | [(_,e)] -> e | (i1,e1) :: x1 -> if y = i1 then e1 else applyenv(x1, y) | [] -> failwith("wrong env") let bind(r, l, e) = (l,e) :: r let rec bindlist(r, il, el) = match (il,el) with | ([],[]) -> r | i::il1, e::el1 -> bindlist (bind(r, i, e), il1, el1) | _ -> raise WrongBindlist end

37 Tipi di dato modificabili §a livello semantico, riconduciamo la modificabilità alla nozione di variabile l lo stato modificabile corrispondente sarà in realtà modellato con il dominio store §per limplementazione usiamo varie strutture dati modificabili come larray

38 Pila modificabile: interfaccia # module type MPILA = sig type 'a stack val emptystack : int * 'a -> 'a stack val push : 'a * 'a stack -> unit val pop : 'a stack -> unit val top : 'a stack -> 'a val empty : 'a stack -> bool val lungh : 'a stack -> int val svuota : 'a stack -> unit val access : 'a stack * int -> 'a exception Emptystack exception Fullstack exception Wrongaccess end

39 Pila modificabile: semantica # module SemMPila: MPILA = struct type 'a stack = ('a SemPila.stack) ref exception Emptystack exception Fullstack exception Wrongaccess let emptystack (n, a) = ref(SemPila.emptystack(n, a) ) let lungh x = SemPila.lungh(!x) let push (a, p) = p := SemPila.push(a, !p) let pop x = x := SemPila.pop(!x) let top x = SemPila.top(!x) let empty x = SemPila.empty !x let rec svuota x = if empty(x) then () else (pop x; svuota x) let rec faccess (x, n) = if n = 0 then SemPila.top(x) else faccess(SemPila.pop(x), n-1) let access (x, n) = let nofpops = lungh(x) n in if nofpops < 0 then raise Wrongaccess else faccess(!x, nofpops) end

40 Pila modificabile: implementazione module ImpMPila: MPILA = struct type 'x stack = ('x array) * int ref exception Emptystack exception Fullstack exception Wrongaccess let emptystack(nm,(x: 'a)) = ((Array.create nm x, ref(-1)): 'a stack) let push(x,((s,n): 'x stack)) = if !n = (Array.length(s) - 1) then raise Fullstack else (Array.set s (!n +1) x; n := !n +1) let top(((s,n): 'x stack)) = if !n = -1 then raise Emptystack else Array.get s !n let pop(((s,n): 'x stack)) = if !n = -1 then raise Emptystack else n:= !n -1 let empty(((s,n): 'x stack)) = if !n = -1 then true else false let lungh( (s,n): 'x stack) = !n let svuota (((s,n): 'x stack)) = n := -1 let access (((s,n): 'x stack), k) = (* if not(k > !n) then *) Array.get s k (* else raise Wrongaccess *) end

41 S-espressioni §la struttura dati fondamentale di LISP l alberi binari con atomi (stringhe) sulle foglie l modificabili §vedremo solo interfaccia e semantica l limplementazione (a heap) simile a quella delle liste

42 S-espressione: interfaccia # module type SEXPR = sig type sexpr val nil : sexpr val cons : sexpr * sexpr -> sexpr val node : string -> sexpr val car : sexpr -> sexpr val cdr : sexpr -> sexpr val null : sexpr -> bool val atom : sexpr -> bool val leaf : sexpr -> string val rplaca: sexpr * sexpr -> unit val rplacd: sexpr * sexpr -> unit exception NotALeaf exception NotACons end

43 S-espressione: semantica # module SemSexpr: SEXPR = struct type sexpr = Nil| Cons of (sexpr ref) * (sexpr ref)| Node of string exception NotACons exception NotALeaf let nil = Nil let cons (x, y) = Cons(ref(x), ref(y)) let node s = Node s let car = function Cons(x,y) -> !x | _ -> raise NotACons let cdr = function Cons(x,y) -> !y | _ -> raise NotACons let leaf = function Node x -> x | _ -> raise NotALeaf let null = function Nil -> true | _ -> false let atom = function Cons(x,y) -> false | _ -> true let rplaca = function (Cons(x, y), z) -> x := z | _ -> raise NotACons let rplacd = function (Cons(x, y), z) -> y := z | _ -> raise NotACons end