1\chapter{Principi Avanzati di Definizione}\label{HOLdefinitions} 2 3\section{I Datatype}\label{sec:datatype} 4\index{definizioni di tipo, nella logica HOL@definizioni di tipo, nella logica \HOL{}!tipi algebrici} 5\index{Hol_datatype@\ml{Hol\_datatype}|(} 6\index{tipi di dato algebrici|see{\ml{Hol\_datatype}}} 7\index{tipi di dato!definizione in HOL@definizione in \HOL{}} 8\index{tipi di dato!definizione in HOL@definizione in \HOL{}|seealso{\ml{Hol\_datatype}}} 9 10Nonostante la logica \HOL{} fornisca principi primitivi di definizione 11che permettono di introdurre nuovi tipi, il livello di dettaglio � 12a grana molto fine. Lo stile delle definizioni di datatype nei linguaggi 13di programmazione funzionale fornisce una motivazione per un interfaccia di 14alto livello per definire datatype algebrici. 15 16La funzione \verb+Hol_datatype+ supporta la definizione di tali 17tipi di dato; le specifiche dei tipi possono essere ricorsive, mutuamente 18ricorsive, ricorsive annidate, e coinvolgere record. La sintassi delle 19dichiarazioni che \verb+Hol_datatype+ accetta si trova nella Tabella 20\ref{datatype}. 21 22\newcommand{\itelse}[3]{\mbox{$\mathtt{if}\ {#1}\ \mathtt{then}\ {#2}\ \mathtt{else}\ {#3}$}} 23 24\newcommand{\bk}{\char'134} 25\newcommand{\ident} {\mbox{\it ident}} 26\newcommand{\clause} {\mbox{\it clause}} 27\newcommand{\type} {\mbox{\it hol\_type}} 28{ 29\newcommand{\binding} {\mbox{\it binding}} 30\newcommand{\recdspec} {\mbox{\it record-spec}} 31\newcommand{\constr} {\mbox{\it constructor-spec}} 32 33\begin{table}[htbp] 34\begin{center} 35\begin{tabular}{|rcl|} 36\hline 37\multicolumn{3}{|l|} 38{\texttt{Hol\_datatype `}[\binding\ \texttt{;}]* \binding\texttt{`}}\\ 39& &\\ 40\binding & \verb+::=+ & \ident\ \verb+=+ \constr\\ 41 & \verb+|+ & \ident\ \verb+=+ \recdspec\\ 42& & \\ 43\constr & \verb+::=+ & [\clause\ \verb+|+]* \clause \\ 44& & \\ 45\clause & \verb+::=+ & \ident \\ 46 & \verb+|+ & \ident\ \verb+of+\ [\type\ \verb+=>+]* \type\\ 47& & \\ 48\recdspec & \verb+::=+ & \verb+<|+ [\ident\ \verb+:+ \type\ \verb+;+]* 49 \ident\ \verb+:+ \type\ \verb+|>+\\ 50 51\hline 52\end{tabular} 53\caption{Dichiarazione di Datatype}\label{datatype} 54\end{center} 55\end{table} 56} 57 58 59\index{definizioni di tipo, nella logica HOL@definizioni di tipo, nella logica \HOL{}!mantenimento della TypeBase@mantenimento della \ml{TypeBase}} 60\index{TypeBase@\ml{TypeBase}} 61% 62\HOL{} mantiene un database sottostante di fatti datatype chiamata la 63\ml{TypeBase}. Questo database � usato per supportare vari strumenti 64di dimostrazione di alto livello (si veda la Sezione~\ref{sec:bossLib}), ed � aumentato ogni volta 65che si fa una dichiarazione \verb+Hol_datatype+. Quando un datatype � 66definito per mezzo di \verb+Hol_datatype+, la seguente informazione � derivata 67e archiviata nel database. 68 69\begin{itemize} 70\item teorema d'inizializzazione per il tipo 71\item iniettivit� dei costruttori 72\item distinzione dei costruttori 73\item teorema d'induzione strutturale 74\item teorema di analisi dei casi 75\item definizione della costante `case' per il tipo 76\item teorema di congruenza per la costante case 77\item definizione della `dimensione' del tipo 78\end{itemize} 79 80Quando il sistema \HOL{} 81si avvia, la \ml{TypeBase} contiene gi� le voci rilevanti per 82i tipi \holtxt{bool}, \holtxt{prod}, \holtxt{num}, \holtxt{option}, 83e \holtxt{list}. 84 85\paragraph{Esempio: Alberi Binari} 86La seguente dichiarazione ML di un tipo di dati di alberi binari 87\begin{hol} 88\begin{verbatim} 89 datatype ('a,'b) btree = Leaf of 'a 90 | Node of ('a,'b) btree * 'b * ('a,'b) btree 91\end{verbatim} 92\end{hol} 93\noindent sarebbe dichiarata in \HOL{} come 94\begin{hol} 95\begin{verbatim} 96 Hol_datatype `btree = Leaf of 'a 97 | Node of btree => 'b => btree` 98\end{verbatim} 99\end{hol} 100\noindent La notazione \holtxt{=>} in una descrizione di datatype HOL 101� intesa sostituire \holtxt{*} in una descrizione di datatype ML, 102e evidenzia il fatto che, in HOL, i costruttori sono di default 103curried. Si noti anche che non � menzionato alcun parametro di tipo 104per il nuovo tipo: le variabili di tipo sono sempre in ordine alfabetivo. 105 106Vale la pena ripetere questo punto delicato: il formato delle definizioni di datatype 107non ha abbastanza informazione per determinare sempre l'ordine degli 108argomenti per gli operatori di tipo introdotti. Cos�, quando si definisce un tipo 109che � polimorfico in pi� di un argomento, c'� la questione di 110quale sar� l'ordine degli argomenti del nuovo operatore. Per un altro 111esempio, se si definisce 112% 113\begin{hol} 114\begin{verbatim} 115 Hol_datatype `sum = Left of 'left | Right of 'right`; 116\end{verbatim} 117\end{hol} 118% 119e poi si scrive \ml{('a,'b)sum}, il valore \ml{'a} sar� sotto il 120costruttore \ml{Left} o \ml{Right}? Il sistema sceglie di far apparire 121gli argomenti corrispondenti alla variabili nell'ordine dato dall'ordine 122alfabetico dei nomi delle variabili. Cos�, nell'esempio 123dato, l'\ml{'a} di \ml{('a,'b)sum} sar� l'argomento \ml{Left} 124perch� \ml{left} viene prima di \ml{right} nell'ordine alfabetico 125standard (ASCII). 126 127\subsection{Ulteriori esempi} 128 129Nel seguito, daremo una panoramica del genere di tipi che 130possono essere definiti per mezzo di \ml{Hol\_datatype}. 131 132Per iniziare, i tipi enumerati possono essere definiti come nel seguente esempio: 133\begin{hol} 134\begin{verbatim} 135 Hol_datatype 136 `enum = A1 | A2 | A3 | A4 | A5 137 | A6 | A7 | A8 | A9 | A10 138 | A11 | A12 | A13 | A14 | A15 139 | A16 | A17 | A18 | A19 | A20 140 | A21 | A22 | A23 | A24 | A25 141 | A26 | A27 | A28 | A29 | A30` 142\end{verbatim} 143\end{hol} 144% 145Altri tipi non ricorsivi possono essere definiti cos�: 146\begin{hol} 147\begin{verbatim} 148 Hol_datatype 149 `foo = N of num 150 | B of bool 151 | Fn of 'a -> 'b 152 | Pr of 'a # 'b` 153\end{verbatim} 154\end{hol} 155% 156Spostandoci ai tipi ricorsivi, abbiamo gi� visto un tipo di alberi 157binari che hanno valori polimorfici presso i nodi interni. Questa volta, 158li dichiareremo in formato ``accoppiato''. 159\begin{hol} 160\begin{verbatim} 161 Hol_datatype 162 `tree = Leaf of 'a 163 | Node of tree # 'b # tree` 164\end{verbatim} 165\end{hol} 166% 167Questa specifica sembra pi� vicina alla dichiarazione che si potrebbe fare 168in ML, ma pu� essere pi� difficile da gestire nella dimostrazione rispetto al 169formato curried usato di sopra. 170 171La sintassi di base del lambda calcolo denominato � facile da descrivere: 172% 173\begin{hol} 174\begin{verbatim} 175 Hol_datatype 176 `lambda = Var of string 177 | Const of 'a 178 | Comb of lambda => lambda 179 | Abs of lambda => lambda` 180\end{verbatim} 181\end{hol} 182% 183La sintassi per i termini `de Bruijn' � pi� o meno simile: 184% 185\begin{hol} 186\begin{verbatim} 187 Hol_datatype 188 `dB = Var of string 189 | Const of 'a 190 | Bound of num 191 | Comb of dB => dB 192 | Abs of dB` 193\end{verbatim} 194\end{hol} 195% 196Gli alberi arbitrariamente ramificanti possono essere definiti permettendo a un nodo di mantenere 197la lista dei suoi sotto-alberi. In un tale caso, i nodi foglia non hanno bisogno di essere 198dichiarati esplicitamente. 199% 200\begin{hol} 201\begin{verbatim} 202 Hol_datatype 203 `ntree = Node of 'a => ntree list` 204\end{verbatim} 205\end{hol} 206% 207Un tipo di `termini del primo ordine' pu� essere dichiarato nel modo seguente: 208% 209\begin{hol} 210\begin{verbatim} 211 Hol_datatype 212 `term = Var of string 213 | Fnapp of string # term list` 214\end{verbatim} 215\end{hol} 216% 217Possono anche essere definiti tipi mutuamente ricorsivi. Il seguente, estratto 218da Elsa Gunter da Definition of Standard ML, cattura un sottoinsieme di 219Core ML. 220% 221\begin{hol} 222\begin{verbatim} 223 Hol_datatype 224 `atexp = var_exp of string 225 | let_exp of dec => exp ; 226 227 exp = aexp of atexp 228 | app_exp of exp => atexp 229 | fn_exp of match ; 230 231 match = match of rule 232 | matchl of rule => match ; 233 234 rule = rule of pat => exp ; 235 236 dec = val_dec of valbind 237 | local_dec of dec => dec 238 | seq_dec of dec => dec ; 239 240 valbind = bind of pat => exp 241 | bindl of pat => exp => valbind 242 | rec_bind of valbind ; 243 244 pat = wild_pat 245 | var_pat of string` 246\end{verbatim} 247\end{hol} 248% 249Tipi record semplici possono essere introdotti usando la notazione \holtxt{<| ... |>}. 250% 251\begin{hol} 252\begin{verbatim} 253 Hol_datatype 254 `state = <| Reg1 : num; Reg2 : num; Waiting : bool |>` 255\end{verbatim} 256\end{hol} 257% 258L'uso di tipi record pu� essere ricorsivo. Per esempio, la seguente 259dichiarazione potrebbe essere usata per formalizzare un semplice file system. 260% 261\begin{hol} 262\begin{verbatim} 263 Hol_datatype 264 `file = Text of string | Dir of directory 265 ; 266 directory = <| owner : string ; 267 files : (string # file) list |>` 268\end{verbatim} 269\end{hol} 270 271\subsection{Definizioni di tipo che falliscono} 272 273Ora ci rivolgiamo ad alcuni tipi che non possono essere dichiarati con \ml{Hol\_datatype}. 274In alcuni casi essi non possono esistere del tutto in HOL; in altri, il tipo 275pu� essere incorporato nella logica HOL, ma \ml{Hol\_datatype} non � in grado di rendere 276la definizione. 277 278Per prima cosa, un tipo vuoto non � permesso in HOL, cos� il seguente tentativo 279� destinato a fallire. 280% 281\begin{hol} 282\begin{verbatim} 283 Hol_datatype 284 `foo = A of foo` 285\end{verbatim} 286\end{hol} 287% 288I cosiddetti `tipi annidati', che occasionalmente sono piuttosto utili, non possono 289al momento essere costruiti con \ml{Hol\_datatype}: 290% 291\begin{hol} 292\begin{verbatim} 293 Hol_datatype 294 `btree = Leaf of 'a 295 | Node of ('a # 'a) btree` 296\end{verbatim} 297\end{hol} 298% 299I tipi non possono eseguire la ricorsione su entrambi i lati delle frecce funzione. La ricorsione 300sulla destra � coerente (si veda la teoria \theoryimp{inftree}), ma 301\ml{Hol\_datatype} non � in grado di definire tipi algebrici che 302la richiedono. Cos�, esempi come il seguente falliranno: 303% 304\begin{hol} 305\begin{verbatim} 306 Hol_datatype 307 `flist = Nil 308 | Cons of 'a => ('b -> flist)` 309\end{verbatim} 310\end{hol} 311% 312La ricorsione sulla sinistra deve fallire per ragioni di cardinalit�. Per 313esempio, HOL non permette il seguente tentativo di modellare il lambda 314calcolo non tipizzato come un insieme (si noti la \holtxt{->} nella clausola per il 315costruttore \holtxt{Abs}): 316% 317\begin{hol} 318\begin{verbatim} 319 Hol_datatype 320 `lambda = Var of string 321 | Const of 'a 322 | Comb of lambda => lambda 323 | Abs of lambda -> lambda` 324\end{verbatim} 325\end{hol} 326 327\subsection{Teoremi che sorgono da una definizione di datatype} 328 329Le conseguenze di un'invocazione di \ml{Hol\_datatype} sono archiviate nell'attuale segmento di teoria e nella \ml{TypeBase}. 330Le principali conseguenze di una definizione di datatype sono i teoremi di ricorsione primitiva e d'induzione. 331Questi forniscono la capacit� di definire semplici funzioni sul tipo, e un principio d'induzione per il tipo. 332\index{teoremi d'induzione, nella logica HOL@teoremi d'induzione, nella logica \HOL{}!per tipi di dato algenrico} 333Cos�, per un tipo denominato \holtxt{ty}, il teorema di ricorsione primitiva � archiviato sono \ml{ty\_Axiom} e il teorema d'induzione � messo sotto \ml{ty\_induction}. 334Altre conseguenze includono la distinzione dei costruttori (\ml{ty\_distinct}), e l'iniettivit� dei costruttori (\verb+ty_11+). 335Una versione `degenerata' di \ml{ty\_induction} � anche archiviata sotto \ml{ty\_nchotomy}: essa prevede ragionamenti per casi sulla costruzione degli elementi di \ml{ty}. 336Infine, sono archiviati alcuni teoremi per scopi speciali: per esempio, \ml{ty\_case\_cong} mantiene un teorema di congruenza per enunciati ``case'' su elementi di \ml{ty}. 337Questi enunciati case sono definiti da \ml{ty\_case\_def}. 338Inoltre, � aggiunta alla teoria attuale una definizione della ``dimensione'' del tipo, sotto il nome \ml{ty\_size\_def}. 339 340Per esempio, l'invocazione 341% 342\begin{hol} 343\begin{verbatim} 344 Hol_datatype 345 `tree = Leaf of num 346 | Node of tree => tree` 347\end{verbatim} 348\end{hol} 349% 350risulta nel fatto che le definizioni 351% 352\begin{hol} 353\begin{verbatim} 354 tree_case_def = 355 |- (!f f1 a. case f f1 (Leaf a) = f a) /\ 356 !f f1 a0 a1. case f f1 (Node a0 a1) = f1 a0 a1 357 358 tree_size_def 359 |- (!a. tree_size (Leaf a) = 1 + a) /\ 360 !a0 a1. tree_size (Node a0 a1) = 1 + (tree_size a0 + tree_size a1) 361\end{verbatim} 362\end{hol} 363% 364sono aggiunte alla teoria attuale. I seguenti teoremi circa i datatype 365sono inoltre dimostrati e archiviati nella teoria attuale. 366% 367\begin{hol} 368\begin{verbatim} 369 tree_Axiom 370 |- !f0 f1. 371 ?fn. (!a. fn (Leaf a) = f0 a) /\ 372 !a0 a1. fn (Node a0 a1) = f1 a0 a1 (fn a0) (fn a1) 373 tree_induction 374 |- !P. (!n. P (Leaf n)) /\ 375 (!t t0. P t /\ P t0 ==> P (Node t t0)) ==> !t. P t 376 tree_nchotomy 377 |- !t. (?n. t = Leaf n) \/ ?t' t0. t = Node t' t0 378 tree_11 379 |- (!a a'. (Leaf a = Leaf a') = (a = a')) /\ 380 !a0 a1 a0' a1'. (Node a0 a1 = Node a0' a1') = (a0=a0') /\ (a1=a1') 381 tree_distinct 382 |- !a1 a0 a. ~(Leaf a = Node a0 a1) 383 tree_case_cong 384 |- !M M' f f1. 385 (M = M') /\ 386 (!a. (M' = Leaf a) ==> (f a = f' a)) /\ 387 (!a0 a1. (M' = Node a0 a1) ==> (f1 a0 a1 = f1' a0 a1)) 388 ==> 389 (tree_CASE M f f1 M = tree_CASE M' f' f1') 390\end{verbatim} 391\end{hol} 392% 393Quando � definito un tipo che coinvolge record, molte pi� definizioni sono 394fatte e aggiunte alla teoria attuale. 395 396Una definizione di tipo mutuamente ricorsiva ha come risultato che i 397teoremi e le definizioni di sopra sono aggiunte per ognuno dei tipi definiti. 398 399\section{Tipi Record}\label{sec:records} 400\index{definizioni di tipo, nella logica HOL@definizioni di tipo, nella logica \HOL{}!tipi record} 401\index{tipi record} 402 403I tipi record sono dei modi convenienti d'impacchettare insieme un numero di 404tipi componenti, e di dare a questi componenti dei nomi cos� da facilitare 405l'accesso ad essi. I tipi record sono semanticamente equivalenti a grandi 406tipi coppia (prodotto), ma la possibilit� di etichettare i campi con nomi di 407propria scelta � una grande comodit�. I tipi record come 408implementati in \HOL{} sono analoghi ai tipi \texttt{struct} del C e ai 409record del Pascal. 410 411Costruiti correttamente, i tipi record forniscono utili funzionalit� di manutenibilit�. 412Se si pu� sempre accedere al campo {\tt fieldn} di un tipo record 413semplicemente scrivendo {\tt record.fieldn}, allora dei cambiamenti al tipo che 414risultano nell'aggiunta o cancellazione di altri campi non invalideranno 415questo riferimento. Una mancanza nei tipi record dell'SML � che non 416permettono la stessa manutenibilit� quando sono interessati degli aggiornamenti 417(funzionali) dei record. L'implementazione HOL permette di scrivere 418\begin{hol} 419\begin{verbatim} 420 rec with fieldn := new_value 421\end{verbatim} 422\end{hol} 423che sostituisce il vecchio valore di {\tt fieldn} nel record {\tt rec} 424con {\tt new\_value}. Non sar� necessario cambiare questa espressione se 425un altro campo � aggiunto, modificato o cancellato dalla definizione originale 426del record. 427 428\paragraph{Definire un tipo record} 429I tipi record sono definiti con la funzione \texttt{Hol\_datatype}, come 430discusso in precedenza. Per esempio, per creare un tipo record chiamato 431{\tt person} con campi booleani, stringa e numero chiamati {\tt 432 employed}, {\tt name} e {\tt age}, si inserirebbe: 433\begin{hol} 434\begin{verbatim} 435 Hol_datatype 436 `person = <| employed : bool ; 437 age : num ; 438 name : string |>` 439\end{verbatim} 440\end{hol} 441L'ordine in cui i campi sono inseriti non � significativo. Oltre 442a definire il tipo (chiamato {\tt person}), la funzione di definizione 443di datatype definisce anche due altre insiemi di costanti. Queste sono le 444funzioni di accesso al campo e le funzioni di aggiornamento funzionale. Le funzioni 445di accesso al campo hanno nomi della forma 446 $\langle$\textsl{record-type\/}$\rangle$\verb|_|$\langle$\textsl{field\/}$\rangle$. 447Queste funzioni possono essere usate direttamente, o si pu� usare la notazione standard 448di accesso ai campi per accedere ai valori del campo di un record. Cos�, 449si scriverebbe l'espressione: \holtxt{bob.employed} allo scopo 450di restituire il valore del campo {\tt employed} di {\tt bob}. 451L'alternativa, \holtxt{person\_employed bob}, funziona, ma sarebbe 452stampata usando la prima sintassi, con il punto.\index{tipi record!notazione di selezione dei campi} 453 454Alle funzioni di aggiornamento funzionale sono dati i nomi 455\mbox{``$\langle$\textsl{record-type}$\rangle$\texttt{\_}$\langle$\textsl{field}$\rangle$\texttt{\_fupd}''} 456per ciascun campo nel 457tipo. Esse prendono due argomenti, una funzione e un record da 458aggiornare. Il parametro funzione � un endomorfismo sul tipo del campo, 459cos� che il record risultante � lo stesso dell'originale, eccetto per il fatto che 460il campo specificato ha avuto la funzione applicata ad esso per 461generare il nuovo valore per quel campo. Esse possono essere scritte con la 462parola chiave \texttt{with} e l'operatore \texttt{updated\_by}. Cos� che 463% 464\begin{hol} 465\begin{verbatim} 466 bob with employed updated_by $~ 467 $ 468\end{verbatim} 469\end{hol}\noindent 470% 471� un valore record identico a \texttt{bob} eccetto per il fatto che il 472valore booleano nel campo \texttt{employed} � stato invertito. 473 474Inoltre, c'� un addolcimento sintattico disponibile per permettere di scrivere un 475record con uno dei suoi campi sostituito da un valore specifico. Questo � 476fatto usando l'operatore \holtxt{:=} al posto di 477\holtxt{updated\_by}: 478% 479\begin{hol} 480\begin{verbatim} 481 bob with employed := T 482\end{verbatim} 483\end{hol} 484% 485Questo forma � tradotta al momento del parsing per essere un uso del corrispondente 486aggiornamento funzionale, insieme con un udo del combinatorio-\textsf{K} dalla 487teoria \texttt{combin}. Perci�, l'esempio di sopra � in realt� 488% 489\begin{hol} 490\begin{verbatim} 491 bob with employed updated_by (K T) 492\end{verbatim} 493\end{hol} 494% 495che a sua volta � una forma pi� carina di 496% 497\begin{hol} 498\begin{verbatim} 499 person_employed_fupd (K T) bob 500\end{verbatim} 501\end{hol} 502% 503Se si desidera una catena di aggiornamenti, allora gli aggiornamenti multipli possono essere 504specificati all'interno di coppie \holtxt{<|}-\holtxt{|>}, separati da 505punti-e-virgola, cos�: 506% 507\begin{hol} 508\begin{verbatim} 509 bob with <| age := 10; name := "Child labourer" |> 510\end{verbatim} 511\end{hol} 512% 513Entrambe le forme di aggiornamento (usando \texttt{updated\_by} e \texttt{:=}) possono essere 514usati in una catena di aggiornamenti. 515 516\paragraph{Specificare letterali record} 517 518Il parser accetta liste di specifiche di campo tra coppie 519\holtxt{<|}-\holtxt{|>} senza la parola chiave \holtxt{with}. 520Queste sono tradotte in sequenze di aggiornamenti di un valore arbitrario 521(letteralmente, il valore HOL \holtxt{ARB}), e sono trattate come letterali. 522Cos�, 523% 524\begin{hol} 525\begin{verbatim} 526 <| age := 21; employed := F; name := "Layabout" |> 527\end{verbatim} 528\end{hol} 529 530\paragraph{Usare i teoremi prodotti da definizioni di record} 531 532Oltre a definire il tipo e le funzioni descritti di sopra, una definizione 533di tipo record dimostra anche una suite di utili teoremi. Questi sono tutti 534salvati (usando {\tt save\_thm}) nel segmento attuale. % 535% 536\index{TypeBase@\ml{TypeBase}} 537% 538Alcuni sono anche aggiunti alle semplificazioni della \ml{TypeBase} per il 539tipo, cos� saranno automaticamente applicati quando si semplifica con il 540simpset \ml{srw\_ss()}, o con le tattiche \ml{RW\_TAC} e 541\ml{SRW\_TAC} (si veda la Sezione~\ref{sec:simpLib}). 542 543Tutti i teoremi sono salvati sotto i nomi che cominciano con il nome del 544tipo. La lista di sotto � un esempio dei teoremi dimostrati. Le 545stringhe d'identificazione sono suffissi appesi al nome del tipo al 546fine di generare il nome finale del teorema. 547 548\newcommand{\rewruse}{Questo teorema � installato nella \texttt{TypeBase}.} 549\newcommand{\field}[1]{\mbox{\it field}_{#1}} 550\newcommand{\update}{\mbox{\tt\_fupd}} 551 552\begin{description} 553\item[\texttt{\_accessors}] Le definizioni delle funzioni di accesso. 554 \rewruse 555\item[\texttt{\_fn\_updates}] Le definizioni delle funzioni di aggiornamento 556 funzionale. 557\item[\texttt{\_accfupds}] Un teorema che stabilisce forme pi� semplici per 558 espressioni che sono della forma $\field{i}\, (\field{j}\update\;f\; r)$. Se 559 $i = j$, allora il lato destro � $f (\field{i}(r))$, se no, � $(\field{i}\;r)$. 560 \rewruse 561\item[\texttt{\_component\_equality}] Un teorema che stabilisce che $(r_1 = 562 r_2) \equiv \bigwedge_i (\field{i}(r_1) = \field{i}(r_2))$. 563\item[\texttt{\_fupdfupds}] Un teorema che stabilisce che $\field{i}\update 564 \;f \,(\field{i}\update \;g\;r) = \field{i}\update\;(f \circ g)\;r$. 565 \rewruse 566\item[\texttt{\_fupdcanon}] Un teorema che stabilisce i risultati di commutativit� 567 per tutte le possibili coppie di aggiornamenti di campo. Essi sono costruiti in 568 un modo tale che se usati come riscritture, renderanno canoniche 569 le sequenze di aggiornamenti. Cos�, per tutti gli $i < j$, � generato \[ 570 \field{j}\update\;f\;(\field{i}\update\;g\;r) = 571 \field{i}\update\;g\;(\field{j}\update\;f\;r) 572 \] 573 \rewruse 574\end{description} 575 576\paragraph{Record grandi} La dimensione di certi teoremi dimostrati nel 577pacchetto tipi record cresce come il quadrato del numero di campi nel 578record. (In particolare, i teoremi di canonicalizzazione dell'aggiornamento e 579e i teoremi \texttt{acc\_fupd} hanno questa propriet�.) Per evitare inefficienza 580con record grandi, l'implementazione dei tipi record usa una 581rappresentazione sottostante pi� efficiente quando il numero dei campi cresce 582troppo. Il punto esatto in cui � applicata questa ottimizzazione � applicata � 583controllato dalla variabile reference 584\texttt{Datatype.big\_record\_size}. Questo valore � inizializzato a 20, 585ma gli utenti possono cambiarlo a scelta. 586 587Sfortunatamente, la rappresentazione di record grandi ha lo svantaggio che 588ogni funzione di aggiornamento e di accesso ha due forme: termini differenti che 589sono stampati allo stesso modo. Una forma � una semplice costante, ed � la forma 590prodotta quando un termine � sottoposto al parsing. L'altra � un p� pi� complicata, ma 591ammette l'uso di teoremi pi� piccoli quando dei valori record sono 592semplificati. Di conseguenza, si raccomanda che i nuovi teoremi, dimostrati 593dall'utente che menzionano campi di record grandi o aggiornamenti di campi passino 594attraverso una fase di semplificazione (\texttt{SIMP\_RULE}), applicando le 595riscritture della \texttt{TypeBase}, prima di essere salvati. 596 597Il pretty-printing di record grandi pu� essere controllato con il 598flag di trace \texttt{pp\_bigrecs}. 599\index{Hol_datatype@\ml{Hol\_datatype}|)} 600 601 602\section{Tipi Quoziente}\label{quotients} 603\index{definizioni di tipo, nella logica HOL@definizioni di tipo, nella logica \HOL{}!quozienti|(} 604\index{tipi quoziente, definizione di} 605 606\HOL{} fornisce una libreria per definire nuovi tipi che sono quozienti 607di tipi esistenti, rispetto alle relazioni di equivalenza parziale. 608Questa libreria � descritta in {\it ``Higher Order Quotients in Higher 609Order Logic''} [HOQ], da cui � presa la seguente descrizione. 610 611Si accede alla libreria quotient aprendo {\tt quotientLib}, 612il che rende accessibili tutti i suoi strumenti e teoremi. 613 614La definizione di nuovi tipi corrispondenti ai quozienti di 615tipi esistenti per relazioni di equivalenza � chiamata ``sollevare'' 616i tipi da un livello inferiore, pi� rappresentativo a uno superiore 617pi� alto. Entrambi i livelli descrivono oggetti simili, ma 618alcuni dettagli che sono evidenti al livello inferiore non sono pi� 619visibili al livello superiore. La logica � semplificata. 620 621Formare semplicemente un nuovo tipo non completa l'operazione quoziente. 622Piuttosto, si desidera ricreare 623%significant parts of the 624l'ambiente logico pre-esistente al nuovo livello, 625pi� alto, e pi� astratto. Questo include non solo i nuovi 626tipi, ma anche le nuove versioni delle costanti che formano e 627manipolano i valori di questi tipi, e anche le nuove versioni dei 628teoremi che descrivono le propriet� di queste costanti. Ognuna di queste 629%must be recreated at the higher level, in order to 630formano uno strato logico, sopra il quale tutti i dettagli rappresentazionali pi� bassi 631si possono dimenticare con sicurezza e per sempre. 632 633Questo si pu� fare in una singola chiamata dello 634strumento principale di questo pacchetto. 635 636\begin{hol} 637\begin{verbatim} 638define_quotient_types : 639 {types: {name: string, 640 equiv: thm} list, 641 defs: {def_name: string, 642 fname: string, 643 func: Term.term, 644 fixity: Parse.fixity} list, 645 tyop_equivs : thm list, 646 tyop_quotients : thm list, 647 tyop_simps : thm list, 648 respects : thm list, 649 poly_preserves : thm list, 650 poly_respects : thm list, 651 old_thms : thm list} -> 652 thm list 653\end{verbatim} 654\end{hol} 655{\tt define\_quotient\_types} prende un singolo argomento che � un 656record con i seguenti campi. 657 658{\it types\/} � una lista di record, ognuno dei quali contiene due campi: 659{\it name}, che � il nome di un nuovo tipo quoziente da creare, e 660{\it equiv}, che � 661o 1) 662un teorema che una relazione binaria {\it R\/} 663� una relazione di equivalenza 664(si veda [HOQ] \S 4) 665della forma 666$$ 667\mbox{\tt |-}\ 668\forall x\ y.\ R\ x\ y \ \Leftrightarrow \ 669 (R\ x = R\ y), 670$$ 671o 2) 672un teorema che {\it R\/} � una relazione di equivalenza parziale non vuota, 673(si veda [HOQ] \S 5) 674della forma 675$$ 676\mbox{\tt |-}\ 677(\exists x.\ R\ x\ x) \ \wedge \ 678(\forall x\ y.\ R\ x\ y \ \Leftrightarrow \ 679 R\ x\ x \wedge R\ y\ y \wedge (R\ x = R\ y)). 680$$ 681Il processo di formare i nuovi tipi quoziente � descritto 682in [HOQ] \S 8. 683 684{\it defs\/} � una lista di record che specifica le costanti da sollevare. 685Ciascun record contiene i seguenti quattro campi: 686{\it func\/} � un termine HOL, che deve essere una singola costante, che � la 687costante da sollevare. 688{\it fname\/} � il nome della nuova costante da definire come la versione sollevata di {\it func}. 689{\it fixity\/} � la fixity HOL della nuova costante da creare, 690come specificato nella struttura HOL {\tt Parse}. 691{\it def\_name} � il nome sotto il quale deve essere archiviata la definizione nella nuova costante 692nella teoria attuale. 693Il 694processo di definire le costanti sollevate 695� descritto in [HOQ] \S 9. 696 697{\it tyop\_equivs\/} � una lista di teoremi di equivalenza condizionali 698per operatori di tipo (si veda [HOQ] \S 4.1). 699Questi sono usati per portare in forma regolare 700i teoremi sui nuovi operatori di tipo, cos� che essi possono essere sollevati 701(si veda [HOQ] \S 11 and \S 12). 702 703{\it tyop\_quotients\/} � una lista di teoremi quoziente condizionali 704per operatori di tipo (si veda [HOQ] \S 5.2). 705Questi sono usati per sollevare sia le costanti sia i teoremi. 706 707{\it tyop\_simps\/} � una lista di teoremi per semplificare relazioni operatori di tipo 708e mappare funzioni, ad esempio, 709{\tt |- (\$= \#\#\# \$=) = \$=} e 710{\tt |- (I \#\# I) = I}. 711 712Il resto degli argomenti si riferisce al processo generale di sollevare i teoremi 713sui quozienti che vengono definiti, 714come descritto in [HOQ] \S 10. 715 716{\it respects\/} � una lista di teoremi circa il rispetto delle 717costanti che sono sollevate. 718Questi teoremi sono descritti in 719[HOQ] \S 10.1. 720 721{\it poly\_preserves\/} � una lista di teoremi circa la preservazione di 722costanti polimorfiche nella logica HOL 723attraverso un'operazione quoziente. 724%as if they were definitions across the quotient operation. 725In altre parole, essi affermano che qualsiasi operazione quozionte preserva queste 726costanti come un omomorfismo. 727Questo teoremi sono descritti in 728[HOQ] \S 10.2. 729 730{\it poly\_respects\/} � una lista di teoremi che mostra il rispetto 731delle costanti polimorfiche menzionate in {\it poly\_preserves}. 732Queste sono 733descritte in 734[HOQ] \S 10.3. 735 736{\it old\_thms\/} � una lista di teoremi che concernono i tipi e le costanti pi� basse, 737rappresentative, che devono essere sollevate e dimostrate automaticamente al 738pi� alto, e pi� astratto livello quoziente. 739Questo teoremi sono descritti in 740[HOQ] \S 10.4. 741 742{\tt define\_quotient\_types} restituisce una lista di teoremi, che sono le 743versioni sollevate degli {\it old\_thms}. 744 745Una funzione analoga, 746{\tt define\_quotient\_types\_rule}, prende un singolo argomento che � un 747record con gli stessi campi di sopra eccetto per {\it old\_thms}, 748e restituisce una funzione SML di tipo {\tt thm -> thm}. 749Questo risultato tipicamente chiamato {\tt LIFT\_RULE}, 750� poi usato per sollevare i vecchi teoremi individualmente, uno alla volta. 751 752Per retro-compatibilit� con 753l'eccellente pacchetto quozienti 754{\tt EquivType} 755creato da 756John Harrison 757%to whom much credit is due, and 758(che ha fornito molta ispirazione), 759� anche fornita la seguente funzione: 760 761\begin{hol} 762\begin{verbatim} 763define_equivalence_type : 764 {name: string, 765 equiv: thm, 766 defs: {def_name: string, 767 fname: string, 768 func: Term.term, 769 fixity: Parse.fixity} list, 770 welldefs : thm list, 771 old_thms : thm list} -> 772 thm list 773\end{verbatim} 774\end{hol} 775\noindent 776Questa funzione � limitata ad un singolo tipo quoziente, ma pu� essere 777pi� conveniente quando la generalit� di {\tt define\_quotient\_types} 778non � necessaria. 779Questa funzione � definita in termini di {\tt define\_quotient\_types} come 780 781\begin{hol} 782\begin{verbatim} 783fun define_equivalence_type {name,equiv,defs,welldefs,old_thms} = 784 define_quotient_types 785 {types=[{name=name, equiv=equiv}], defs=defs, tyop_equivs=[], 786 tyop_quotients=[FUN_QUOTIENT], 787 tyop_simps=[FUN_REL_EQ,FUN_MAP_I], respects=welldefs, 788 poly_preserves=[FORALL_PRS,EXISTS_PRS], 789 poly_respects=[RES_FORALL_RSP,RES_EXISTS_RSP], 790 old_thms=old_thms}; 791\end{verbatim} 792\end{hol} 793\index{definizioni di tipo, nella logica HOL@definizioni di tipo, nella logica \HOL{}!quozienti|)} 794 795 796\section{Espressioni Case}\label{CaseExp} 797\index{case expressions|(} 798 799All'interno della logica \HOL{}, le espressioni case forniscono una notazione molto compatta e conveniente per la selezione multi-way tra i valori di pi� espressioni. 800Questo � modellato sui costrutti case nei linguaggi di programmazione funzionale come lo Standard ML. 801Tali espressioni case possono semplificare l'espressione di rami complicati tra casi differenti o combinazioni di casi. 802La sintassi base (dove il $\mathit{term}$ non-terminale sta per qualsiasi termine \HOL{}) � 803\begin{eqnarray*} 804\mathit{term} & ::= & \texttt{case}\;\mathit{term}\;\texttt{of}\;\mathit{cases}\\ 805\mathit{cases} &::= & \mathit{case}_1 \;\mathit{morecases}\\ 806\mathit{case}_1 & ::= & \texttt{\bfseries |}\;\mathit{case} \;\;\;|\;\;\;\mathit{case}\\ 807\mathit{morecases} & ::= & \varepsilon\;\;\;|\;\;\;\texttt{|}\;\mathit{case}\;\mathit{morecases}\\ 808\mathit{case} & ::= & \mathit{term} \;\texttt{=>}\; \mathit{term} 809\end{eqnarray*} 810La scelta nella regola per il primo caso ($\mathit{case}_1$) permette l'uso di una sintassi pi� uniforme, dove ciascun caso � preceduto da una barra verticale. 811Omettendo la barra, che � ci� che fa il pretty-printer quando la sintassi � stampata, si conforma con la sintassi usata dall'SML. 812 813Sulla base del valore di una espressione di test, sono considerate in sequenza una lista di 814espressioni pattern per vedere se si accordano con l'espressione di test. 815Il primo pattern che matcha con successo fa s� che l'espressione risultato ad esso 816associata sia valutata e il suo valore restituito come il valore dell'intera 817espressione case. Per esempio, 818% 819\begin{hol} 820\begin{verbatim} 821 case n of 822 0 => "none" 823 | 1 => "one" 824 | 2 => "two" 825 | _ => "many" 826\end{verbatim} 827\end{hol} 828% 829 830Questo avrebbe potuto essere espresso usando diversi costrutti ``if--then--else'', 831ma l'espressione case � molto pi� compatta e pulita, con la 832selezione tra varie scelte rese chiaramente evidenti. 833 834Oltre ai letterali come pattern, come di sopra, i pattern possono essere 835espressioni costruttore. Molti tipi standard \HOL{} hanno dei costruttori, 836compresi \ml{num}, \ml{list}, e \ml{option}. 837% 838\begin{hol} 839\begin{verbatim} 840 case spouse(employee) of 841 | NONE => "single" 842 | SOME s => "married to " ++ name_of s 843\end{verbatim} 844\end{hol} 845(Questo esempio usa la barra opzionale all'inizio del primo caso.) 846 847\HOL{} supporta una ricca struttura di espressioni case che usano una singola 848notazione. Il formato � legato a quello delle definizioni di funzioni 849ricorsive, come descritto nella Sezione~\ref{TFL}. Inoltre, le espressioni 850case possono contenere letterali come pattern, o singolarmente come 851elementi di pattern pi� profondamente annidati. 852 853Le espressioni case possono testare valori di qualsiasi tipo. Se l'espressione test 854� un tipo con costruttori, allora i pattenr possono essere espressi 855usando i costruttori applicati agli argomenti, come per esempio \ml{SOME s} 856nell'esempio di sopra. Una variabile libeera all'interno del pattern costruttore, 857per esempio \ml{s} nel pattern \ml{SOME s}, diventa legata al 858corrispondente valore all'interno del valore dell'espressione di test, e 859pu� essere usata all'interno dell'espressione risultato associata per quel pattern. 860 861Oltre ai costruttori per i tipi standard in \HOL{}, 862i pattern costruttore possono essere usati anche per i tipi creati per mezzo della 863definizione di datatype descritta nella Sezione~\ref{sec:datatype}, 864compresi i tipi definiti dall'utente. 865 866Sia che l'espressione di testi sia un tipo con costruttori o meno, 867i pattern possono essere espressi usando i letterali appropriati di quel tipo, 868se esistono tali letterali. 869Un pattern complesso pu� contenere o letterali o pattern costruttore 870o entrambi annidati l'uno con l'altro. 871Tuttavia, i letterali e i costruttori non possono essere mischiati come alternative 872gli uni degli altri all'interno della stessa espressione case, 873a meno che un particolare pattern possa essere sia un letterale 874e anche un costruttore (0-ario) del suo tipo, come per esempio \ml{0} (zero) 875� sia un letterale sia un costruttore del tipo \ml{num}. 876Qui c'� un esempio di questo genere di miscuglio improprio. 877% 878\begin{hol} 879\begin{verbatim} 880 case n of 881 0 => "none" 882 | 1 => "one" 883 | 2 => "two" 884 | SUC m => "many" 885\end{verbatim} 886\end{hol} 887% 888In questo pattern, il pattern costruttore \ml{SUC m} � dato come 889un'alternativa ai pattern letterali \ml{1} and \ml{2}. 890Ci� rende questo espressione case invalida. 891Cancellare uno dei due gruppi di righe risolverebbe il conflitto, 892e renderebbe valida l'espressione. 893Si noti che il pattern \ml{0} � accettabile per entrambi i gruppi. 894 895Anche i pattern possono essere nidificati, come mostrato nel prossimo esempio, dove 896la funzione \ml{parents} restituisce una coppia contenente il padre della persona 897e/o la madre, dove ciascuno � rappresentato da \ml{NONE} se deceduto. 898% 899\begin{hol} 900\begin{verbatim} 901 case parents(john) of 902 (NONE,NONE) => "orphan" 903 | _ => "not an orphan" 904\end{verbatim} 905\end{hol} 906% 907Questo mostra l'annidamento di pattern option all'interno di un pattern coppia, 908e anche l'uso di una wildcard \ml{\_} per matchare i casi non forniti. 909 910Se l'insieme di pattern � rado [sparse nel testo originale (ndt)], ci possono essere alcune nuove righe generate 911automaticamente per compilarlo, e possibilmente alcune nuove variabili o la 912costante \ml{ARB} per rappresentare propriamente l'espressione case. 913% 914\begin{hol} 915\begin{verbatim} 916- ``case a of 917 (1, y, z) => y + z 918 | (x, 2, z) => x - z 919 | (x, y, 3) => x * y``; 920> val it = 921 ``case a of 922 (1,2,3) => 2 + 3 923 | (1,2,z) => 2 + z 924 | (1,y,3) => y + 3 925 | (1,y,z) => y + z 926 | (x,2,3) => x - 3 927 | (x,2,z') => x - z' 928 | (x,y',3) => x * y' 929 | (x,y',z') => ARB`` : term 930\end{verbatim} 931\end{hol} 932 933Questo � soltanto una breve descrizione di alcune delle 934capacit� espressive dell'espressione case con pattern. 935Molti altri esempi di pattern sono forniti nella Sezione~\ref{TFL} 936sulla definizione delle funzioni ricorsive. 937 938\index{espressioni case|)} 939 940 941\section{Funzioni Ricorsive}\label{TFL} 942 943\HOL{} fornisce una meccanismo di definizione di funzione basato sul 944teorema di ricorsione benfondata fornito in \theoryimp{relationTheory}, 945discusso nella Sezione~\ref{relation}. \ml{Define} prende una specifica di alto livello, 946possibilmente ricorsiva, di una funzione e tenta di 947definire la funzione nella logica. \ml{Define} pu� essere usato per definire 948abbreviazioni, funzioni ricorsive, e funzioni mutuamente 949ricorsive. Un teorema d'induzione pu� essere generato come un sotto-prodotto 950dell'attivit� di \ml{Define}. Questo teorema d'induzione segue la struttura 951ricorsiva della funzione, e pu� essere utile quando di dimostrano propriet� 952della funzione. \ml{Define} non ha sempre successo nel tentare di 953eseguire la definizione specificata, di solito perch� una dimostrazione 954automatica di terminazione fallisce: in quel caso, si pu� usare un altro punto d'entrata, 955\ml{Hol\_defn}, rinvia la dimostrazione di terminazione all'utente. 956La tecnologia che sottosta a \ml{Define} e \ml{Hol\_defn} � spiegata 957in dettaglio in Slind~\cite{slind-thesis}. 958 959 960\index{Define@\ml{Define}} 961 962In particolare, \ml{Define} prende come input una quotation che rappresenta una 963congiunzione di equazioni. La (o le) funzione (funzioni) specificate possono essere formulate 964usando un pattern-matching in stile ML. Una chiamata 965\ml{Define `}\textit{spec}\ml{`} dovrebbe conformarsi con la grammatica nella Tabella 966\ref{define:syntax}. 967\begin{table}[htbp] 968\begin{center} 969$ 970\begin{array}{|rll|} 971\hline 972\mathit{spec} & ::= & \mathit{eqn} \\ 973 & \mid & (\mathit{eqn}) \land \mathit{spec} \\ 974 & & \\ 975\mathit{eqn} & ::= & \mathit{alphanumeric}\ \mathit{pat} \ldots \mathit{pat} = \mathit{term} \\ 976 & & \\ 977 & & \\ 978\mathit{pat} & ::= & \mathit{variable} \\ 979 & \mid & \mathit{wildcard} \\ 980 & \mid & \mathit{cname} \\ 981 & \mid & (\mathit{cname}_n\ \mathit{pat}_1 \ldots \mathit{pat}_n) \\ 982 & & \\ 983\mathit{cname} & ::= & \mathit{alphanumeric} \mid \mathit{symbolic} \\ 984 & & \\ 985\mathit{wildcard} & ::= & \_\!\_ \\ 986 & \mid & \_\!\_ \mathit{wildcard} \\ 987 & & \\ 988\hline 989\end{array} 990$ 991\caption{Sintassi della Dichiarazione di Funzione}\label{define:syntax} 992\end{center} 993\end{table} 994 995\paragraph{Espansione di Pattern} 996In generale, \ml{Define} tenta di derivare esattamente la congiunzione 997di equazioni specificata. Tuttavia, la ricca sintassi dei pattern ammette 998qualche ambiguit�. Per esempio, l'input 999% 1000\begin{hol} 1001\begin{verbatim} 1002 Define `(f 0 _ = 1) 1003 /\ (f _ 0 = 2)` 1004\end{verbatim} 1005\end{hol} 1006% 1007� ambiguo per \holtxt{f 0 0}: il risultato dovrebbe essere \holtxt{1} o 1008\holtxt{2}? Questa ambiguit� � gestita ne modo usuale per i compilatori e 1009gli interpreti per i linguaggi funzionali: cio�, la congiunzione delle 1010equazioni � trattata come fosse applicata prima la congiunzione sinistra, seguita 1011dall'elaborazione del congiunto destro. Quindi, nell'esempio di sopra, il 1012valore di \holtxt{f 0 0} � \holtxt{1}. Nell'implementazione, 1013le ambiguit� che sorgono da tali pattern sovrapposti sono tradotti 1014sistematicamente in un passo di pre-elaborazione. 1015 1016Un altro caso di ambiguit� nei pattern � mostrato di sotto: la specifica 1017� incompleta dal momento che non dice come \holtxt{f} dovrebbe comportarsi quando 1018applicata a due argomenti diversi da zero: ad esempio, \holtxt{f (SUC m) (SUC n)}. Nella 1019implementazione, tali clausole mancanti sono riempite, e hanno il valore 1020\holtxt{ARB}. Questo passo di `completamento del pattern' � un modo di trasformare le descrizioni 1021di funzioni parziali in funzioni totali adatte per HOL. Tuttavia, 1022dal momento che l'utente non specificato in modo completo la funzione, il sistema 1023lo prende come un suggerimento che l'utente non � interessato nell'usare la 1024funzione per le clausole mancanti ma riempite, e cos� tali clausole sono 1025eliminate dal teorema finale. 1026 1027In sintesi, \ml{Define} deriver� le equazioni non ambigue e 1028complete 1029% 1030\begin{hol} 1031\begin{verbatim} 1032 |- (f 0 (SUC v4) = 1) /\ 1033 (f 0 0 = 1) /\ 1034 (f (SUC v2) 0 = 2) 1035 (f (SUC v2) (SUC v4) = ARB) 1036\end{verbatim} 1037\end{hol} 1038% 1039dall'equazioni ambigue e incomplete di sopra. Gli strani 1040nomi delle variabili sono dovuti ai passi di pre-elaborazione descritti di sopra. Il 1041risultato di sopra � solo un valore intermedio: nel risultato finale restituito 1042da \ml{Define}, l'ultima equazione � rimossa dal momento che non � stata 1043specificata dall'input originale. 1044 1045\begin{hol} 1046\begin{verbatim} 1047 |- (f 0 (SUC v4) = 1) /\ 1048 (f 0 0 = 1) /\ 1049 (f (SUC v2) 0 = 2) 1050\end{verbatim} 1051\end{hol} 1052 1053\paragraph{Terminazione} 1054 1055Durante l'elaborazione della specifica di una funzione ricorsiva, \ml{Define} 1056deve eseguire una dimostrazione di terminazione. Essa costruisce automaticamente 1057delle condizioni di terminazione per la funzione, e invoca un dimostratore 1058di terminazione nel tentativo di dimostrare le condizioni di terminazione. Se la 1059funzione � ricorsiva primitiva, nel senso che segue esattamente 1060il pattern ricorsione di un datatype HOL dichiarato in precedenza, allora questa 1061dimostrazione avr� sempre successo, e \ml{Define} archivia l'equazioni derivate nel 1062segmento attuale di teoria. 1063Altrimenti, la funzione non � 1064un'istanza di ricorsione primitiva, e il dimostratore di terminazione pu� 1065avere successo o fallire. Se la dimostrazione di terminazione fallisce, allora \ml{Define} fallisce. 1066Se ha successo, allora \ml{Define} archivia l'equazioni specificate nell'attuale 1067segmento di teoria. E' anche archiviato nell'attuale segmento di teoria un teorema d'induzione 1068customizzato per la funzione specificata. Si noti, tuttavia, che 1069non � archiviato un teorema d'induzione per le funzioni ricorsive primitive, dal 1070momento che quel teorema sarebbe identico al teorema d'induzione che risulta 1071dalla dichiarazione del datatype. 1072 1073 1074\paragraph{Archiviare le definizioni nel segmento di teoria} 1075 1076\ml{Define} genera automaticamente nomi con i quali archiviare la 1077definizione e, (se esiste) il teorema d'induzione associato, nella teoria 1078attuale. Il nome per archiviare la definizione � costruito 1079concatenando il nome della funzione con il valore della variabile 1080reference \ml{Defn.def\_suffix}. Il nome per archiviare il teorema d'induzione 1081� costruito concatenando il nome della funzione con il valore 1082della variabile reference \ml{Defn.ind\_suffix}. Per funzioni 1083mutuamente ricorsive, dove c'� una scelta di nomi, � preso il nome della funzione 1084nella prima clausola. 1085 1086Dal momento che i nomi usati per archiviare elementi nel segmento attuale di teoria 1087sono trasformati in binding ML dopo che la teoria � esportata, � 1088richiesto che ogni invocazione di \ml{Define} generi nomi che sono 1089identificatori ML validi. Per questa ragione, \ml{Define} richiede 1090nomi alfanumerici di funzione. Se si desidera definire identificatori 1091simbolici, si dovrebbe usare la funzione ML \ml{xDefine}. 1092 1093\index{xDefine@\ml{xDefine}} 1094\begin{hol} 1095\begin{verbatim} 1096 xDefine : string -> term quotation -> thm 1097\end{verbatim} 1098\end{hol} 1099La funzione \ml{xDefine} � identica a 1100\ml{Define} eccetto per il fatto che prende un nome esplicito da usare quando 1101si archivia la definizione nella teoria attuale. 1102 1103\subsection{Esempi di definizione di funzione} 1104Daremo un numero di esempi che mostrano la gamma di funzioni 1105che possono essere definite con \ml{Define}. Innanzi tutto, abbiamo una funzione ricorsiva 1106che usa ``de-costruttori'' nella chiamata ricorsiva. 1107 1108\begin{hol} 1109\begin{verbatim} 1110 Define 1111 `fact x = if x = 0 then 1 else x * fact(x-1)`; 1112 1113 Equations stored under "fact_def". 1114 Induction stored under "fact_ind". 1115 > val it = |- fact x = (if x = 0 then 1 else x * fact (x - 1)) : thm 1116\end{verbatim} 1117\end{hol} 1118% 1119Dal momento che \holtxt{fact} non � 1120ricorsiva primitiva, � generato un teorema d'induzione per \holtxt{fact} e 1121archiviato nella teoria attuale. 1122% 1123\begin{hol} 1124\begin{verbatim} 1125 - DB.fetch "-" "fact_ind"; 1126 1127 > val it = 1128 |- !P. (!x. (~(x = 0) ==> P (x - 1)) ==> P x) ==> !v. P v : thm 1129\end{verbatim} 1130\end{hol} 1131 1132Poi abbiamo una funzione ricorsiva con un pattern-matching 1133relativamente complesso. Tralasciamo di esaminare il teorema 1134d'induzione generato. 1135% 1136\begin{hol} 1137\begin{verbatim} 1138 Define `(flatten [] = []) 1139 /\ (flatten ([]::rst) = flatten rst) 1140 /\ (flatten ((h::t)::rst) = h::flatten(t::rst))`; 1141 1142 Equations stored under "flatten_def". 1143 Induction stored under "flatten_ind". 1144 1145 > val it = 1146 |- (flatten [] = []) /\ 1147 (flatten ([]::rst) = flatten rst) /\ 1148 (flatten ((h::t)::rst) = h::flatten (t::rst)) : thm 1149\end{verbatim} 1150\end{hol} 1151 1152Poi definiamo una funzione ricorsiva curried, che usa 1153espansione di caratteri jolly e pre-elaborazione di pattern-matching. 1154% 1155\begin{hol} 1156\begin{verbatim} 1157 Define `(min (SUC x) (SUC y) = min x y + 1) 1158 /\ (min ____ ____ = 0)`; 1159 1160 Equations stored under "min_def". 1161 Induction stored under "min_ind". 1162 1163 > val it = 1164 |- (min (SUC x) (SUC y) = min x y + 1) /\ 1165 (min (SUC v2) 0 = 0) /\ 1166 (min 0 v1 = 0) : thm 1167\end{verbatim} 1168\end{hol} 1169 1170Poi facciamo una definizione ricorsiva primitiva. Si noti che, in questo caso, non 1171� generato alcun teorema d'induzione. 1172% 1173\begin{hol} 1174\begin{verbatim} 1175 Define `(filter P [] = []) 1176 /\ (filter P (h::t) = if P h then h::filter P t else filter P t)`; 1177 1178 Definition has been stored under "filter_def". 1179 1180 > val it = 1181 |- (!P. filter P [] = []) /\ 1182 !P h t. filter P (h::t) = 1183 (if P h then h::filter P t else filter P t) : thm 1184\end{verbatim} 1185\end{hol} 1186 1187\ml{Define} pu� essere usata anche per definire funzioni mutuamente ricorsive. 1188Per esempio, possiamo definire un datatype di proposizioni e una funzione per 1189mettere una proposizione in forma normale negata come segue. 1190Prima definiamo un datatype, chiamato \ml{prop}, di formule booleane: 1191% 1192\begin{hol} 1193\begin{verbatim} 1194 Hol_datatype 1195 `prop = VAR of 'a 1196 | NOT of prop 1197 | AND of prop => prop 1198 | OR of prop => prop`; 1199\end{verbatim} 1200\end{hol} 1201% 1202Poi sono definite due funzioni mutuamente ricorsive 1203\holtxt{nnfpos} e \holtxt{nnfneg}: 1204% 1205\begin{hol} 1206\begin{verbatim} 1207 Define 1208 `(nnfpos (VAR x) = VAR x) 1209 /\ (nnfpos (NOT p) = nnfneg p) 1210 /\ (nnfpos (AND p q) = AND (nnfpos p) (nnfpos q)) 1211 /\ (nnfpos (OR p q) = OR (nnfpos p) (nnfpos q)) 1212 1213 /\ (nnfneg (VAR x) = NOT (VAR x)) 1214 /\ (nnfneg (NOT p) = nnfpos p) 1215 /\ (nnfneg (AND p q) = OR (nnfneg p) (nnfneg q)) 1216 /\ (nnfneg (OR p q) = AND (nnfneg p) (nnfneg q))` 1217\end{verbatim} 1218\end{hol} 1219% 1220The system makes the definition and returns the theorem 1221% 1222\begin{hol} 1223\begin{verbatim} 1224 |- (nnfpos (VAR x) = VAR x) /\ 1225 (nnfpos (NOT p) = nnfneg p) /\ 1226 (nnfpos (AND p q) = AND (nnfpos p) (nnfpos q)) /\ 1227 (nnfpos (OR p q) = OR (nnfpos p) (nnfpos q)) /\ 1228 (nnfneg (VAR x) = NOT (VAR x)) /\ 1229 (nnfneg (NOT p) = nnfpos p) /\ 1230 (nnfneg (AND p q) = OR (nnfneg p) (nnfneg q)) /\ 1231 (nnfneg (OR p q) = AND (nnfneg p) (nnfneg q)) : thm 1232\end{verbatim} 1233\end{hol} 1234 1235\ml{Define} pu� anche essere usata per definire funzioni non-ricorsive. 1236% 1237\begin{hol} 1238\begin{verbatim} 1239 Define 1240 `f x (y,z) = (x + 1 = y DIV z)`; 1241\end{verbatim} 1242\end{hol} 1243 1244\ml{Define} pu� essere usata anche per definire funzioni non-ricorsive 1245con un pattern-matching complesso. La pre-elaborazione del pattern-matching di 1246\ml{Define} pu� essere conveniente per questo scopo, ma pu� anche generare un 1247grande numero di equazioni. Per esempio: 1248% 1249\begin{hol} 1250\begin{verbatim} 1251 Define 1252 `(g (0,_,_,_,_) = 1) /\ 1253 (g (_,0,_,_,_) = 2) /\ 1254 (g (_,_,0,_,_) = 3) /\ 1255 (g (_,_,_,0,_) = 4) /\ 1256 (g (_,_,_,_,0) = 5)` 1257\end{verbatim} 1258\end{hol} 1259% 1260restituisce una definizione con trentuno clausole. 1261 1262 1263\subsection{Quando la terminazione non � dimostrata automaticamente} 1264 1265Se la dimostrazione di terminazione per una definizione potenziale 1266fallisce, l'invocazione di \ml{Define} (o \ml{xDefine}) fallisce. In tali 1267situazioni, si dovrebbe usare la funzione \ML{} \ml{Hol\_defn}. 1268% 1269\index{Hol_defn@\ml{Hol\_defn}} 1270 1271\begin{hol} 1272\begin{verbatim} 1273 Hol_defn : string -> term quotation -> Defn.defn 1274\end{verbatim} 1275\end{hol} 1276 1277\ml{Hol\_defn} esegue la definizione richiesta, ma rinvia la dimostrazione di 1278terminazione all'utente. Per la creazione di dimostrazioni di terminazione, esistono 1279alcuni utili entrypoint, cio� 1280\begin{hol} 1281\begin{verbatim} 1282 Defn.tgoal : Defn.defn -> GoalstackPure.proofs 1283 Defn.tprove : Defn.defn * tactic -> thm * thm 1284\end{verbatim} 1285\end{hol} 1286\ml{Defn.tgoal} � analogo a \ml{set\_goal} e \ml{Defn.tprove} � 1287analogo a \ml{prove}, Cos�, \ml{Defn.tgoal} � usato per prendere il 1288risultato di \ml{Hol\_defn} e creare un goal per dimostrare la terminazione 1289della definizione. 1290 1291\paragraph{Esempio.} Un'invocazione di {\small\verb+Define+} sulle 1292seguenti equazioni per Quicksort attualmente fallir�, dal momento che la 1293dimostrazione di terminazione � attualmente oltre le capacit� del dimostratore elementare 1294di terminazione. Piuttosto, eseguiamo un'applicazione di {\small\verb+Hol_defn+}: 1295 1296\setcounter{sessioncount}{0} 1297\begin{session} 1298\begin{verbatim} 1299 val qsort_def = 1300 Hol_defn "qsort" 1301 `(qsort ord [] = []) /\ 1302 (qsort ord (h::t) = 1303 qsort ord (FILTER (\x. ord x h) t) 1304 ++ [h] ++ 1305 qsort ord (FILTER (\x. ~(ord x h)) t))` 1306\end{verbatim} 1307\end{session} 1308che restituisce il seguente valore di tipo \ml{defn}, ma non tenta di 1309dimostrare la terminazione. 1310\begin{session} 1311\begin{verbatim} 1312 HOL function definition (recursive) 1313 1314 Equation(s) : 1315 [...] |- qsort ord [] = [] 1316 [...] 1317 |- qsort ord (h::t) = 1318 qsort ord (FILTER (\x. ord x h) t) ++ [h] ++ 1319 qsort ord (FILTER (\x. ~ord x h) t) 1320 1321 Induction : 1322 [...] 1323 |- !P. 1324 (!ord. P ord []) /\ 1325 (!ord h t. 1326 P ord (FILTER (\x. ~ord x h) t) /\ 1327 P ord (FILTER (\x. ord x h) t) ==> 1328 P ord (h::t)) ==> 1329 !v v1. P v v1 1330 1331 Termination conditions : 1332 0. !t h ord. R (ord,FILTER (\x. ~ord x h) t) (ord,h::t) 1333 1. !t h ord. R (ord,FILTER (\x. ord x h) t) (ord,h::t) 1334 2. WF R 1335\end{verbatim} 1336\end{session} 1337 1338Il tipo \ml{defn} ha un prettyprinter installato per esso: l'output 1339di sopra � tipico, mostrando i componenti di una \ml{defn} in un formato 1340comprensibile. Bench� sia possibile lavorare direttamente con elementi di 1341tipo \ml{defn}, � pi� conveniente invocare 1342\ml{Defn.tgoal}, che imposta una dimostrazione di terminazione in un goalstack. 1343% 1344\begin{session} 1345\begin{verbatim} 1346 Defn.tgoal qsort_def; 1347 1348 > val it = 1349 Proof manager status: 1 proof. 1350 1. Incomplete: 1351 Initial goal: 1352 ?R. 1353 (!t h ord. R (ord,FILTER (\x. ~ord x h) t) (ord,h::t)) /\ 1354 (!t h ord. R (ord,FILTER (\x. ord x h) t) (ord,h::t)) /\ WF R 1355\end{verbatim} 1356\end{session} 1357% 1358Il goal � trovare una relazione benfondata sugli argomenti per \holtxt{qsort} 1359e mostrare che gli argomenti per \holtxt{qsort} sono nella relazione. 1360La funzione \ml{WF\_REL\_TAC} � quasi sempre utilizzata a questo punto per 1361iniziare la dimostrazione di terminazione. Chiaramente, \ml{qsort} termina perch� la lista 1362argomento diventa pi� piccola. L'invocazione di \ml{WF\_REL\_TAC} con la funzione di misura 1363appropriata risulta in due subgoal, ognuno dei quali � facile da 1364dimostrare. 1365 1366\begin{session} 1367\begin{verbatim} 1368 - e (WF_REL_TAC `measure (LENGTH o SND)`); 1369 OK.. 1370 2 subgoals: 1371 > val it = 1372 !t h ord. LENGTH (FILTER (\x. ord x h) t) < LENGTH (h::t) 1373 1374 !t h ord. LENGTH (FILTER (\x. ~ord x h) t) < LENGTH (h::t) 1375\end{verbatim} 1376\end{session} 1377% 1378L'esecuzione di \ml{WF\_REL\_TAC} ha dimostrato automaticamente la 1379benfondatezza della relazione di terminazione 1380\holtxt{measure (LENGTH o SND)} 1381e il resto del goal � stato semplificato in una 1382coppia di goal semplici. Una volta che entrambi i goal sono dimostrati, possiamo incapsulare 1383la relazione di terminazione con \ml{tDefine}, che prende una quotation 1384(che rappresenta l'equazioni di ricorsione desiderate) e una tattica $t$, 1385definisce la funzione specificata, calcola le condizioni di terminazione, 1386e applica $t$ ad esse. Se le condizioni di terminazione sono dimostrate da 1387$t$ allora l'equazioni di ricorsione e il teorema d'induzione sono archiviati 1388nel segmento di teoria attuale prima che le equazioni di ricorsione siano restituite: 1389 1390\begin{session} 1391\begin{verbatim} 1392 - val qsort_def = tDefine "qsort" 1393 `(qsort ord [] = []) /\ 1394 (qsort ord (h::t) = 1395 qsort ord (FILTER (\x. ord x h) t) ++ [h] ++ 1396 qsort ord (FILTER (\x. ~(ord x h)) t))` 1397 (WF_REL_TAC `measure (LENGTH o SND)` THEN ...); 1398 1399 > val qsort_def = 1400 |- (qsort ord [] = []) /\ 1401 (qsort ord (h::t) = 1402 qsort ord (FILTER (\x. ord x h) t) ++ [h] ++ 1403 qsort ord (FILTER (\x. ~ord x h) t)) : thm 1404\end{verbatim} 1405\end{session} 1406 1407Il teorema d'induzione custom per una funzione si pu� ottenere usando \holtxt{fetch}, 1408che restituisce elementi nominati nella teoria specifica\footnote{In una chiamata a \texttt{fetch}, il 1409primo argomento denota una teoria; la teoria attuale pu� essere specificata da \texttt{"-"}.}. 1410\begin{session} 1411\begin{verbatim} 1412 - fetch "-" "qsort_ind"; 1413 > val qsort_ind = 1414 |- !P. 1415 (!ord. P ord []) /\ 1416 (!ord h t. 1417 P ord (FILTER (\x. ~ord x h) t) /\ 1418 P ord (FILTER (\x. ord x h) t) ==> P ord (h::t)) 1419 ==> 1420 !v v1. P v v1 : thm 1421\end{verbatim} 1422\end{session} 1423 1424\noindent Il teorema d'induzione prodotto da \holtxt{Define} e \holtxt{tDefine} pu� 1425essere applicato da \ml{recInduct}. Si veda la Sezione \ref{sec:bossLib} per i dettagli. 1426 1427 1428\subsubsection{Tecniche per dimostrare la terminazione} 1429 1430Ci sono due problemi da affrontare quando di tenta di dimostrare la terminazione. 1431Primo, bisogna comprendere, intuitivamente e poi matematicamente, 1432perch� la funzione in considerazione termina. Secondo, si deve 1433essere in grado di formulare questo in \HOL. In ci� che segue, daremo alcuni 1434esempi di come questo � fatto. 1435 1436C'� un certo numero di strumenti base e avanzati per specificare relazioni 1437benfondate. Il punto di partenza pi� comune per trattare i problemi 1438di terminazione per funzioni ricorsive � trovare qualche funzione, conosciuta come una 1439\emph{misura} sotto la quale gli argomenti di una chiamata di funzione sono pi� grandi 1440degli argomenti a qualsiasi chiamata ricorsiva che ne risulta. 1441 1442Per un esempio di partenza molto semplice, si consideri la seguente definizione 1443di una funzione che calcola il massimo comun divisore di due 1444numeri: 1445% 1446\setcounter{sessioncount}{0} 1447\begin{session} 1448\begin{verbatim} 1449 - val gcd_defn = 1450 Hol_defn "gcd" 1451 `(gcd (0,n) = n) /\ 1452 (gcd (m,n) = gcd (n MOD m, m))`; 1453 1454 - Defn.tgoal gcd_defn; 1455 1456 > val it = 1457 Proof manager status: 1 proof. 1458 1. Incomplete: 1459 Initial goal: 1460 ?R. WF R /\ !v2 n. R (n MOD SUC v2,SUC v2) (SUC v2,n) 1461\end{verbatim} 1462\end{session} 1463% 1464L'invocazione \holtxt{gcd(m,n)} esegue una ricorsione nel suo primo argomento, e 1465dal momento che sappiamo che \holtxt{m} non � 0, si da il caso che 1466\holtxt{n MOD m} sia pi� piccolo di \holtxt{m}. Il modo di formulare la 1467terminazione di \holtxt{gcd} in HOL � di usare una funzione `misura' 1468per mappare dal dominio di \holtxt{gcd}---una coppia di numeri---a un numero. 1469La definizione di {misura} in \HOL{} � equivalente a 1470% 1471\begin{hol} 1472\begin{verbatim} 1473 |- measure f x y = (f x < f y). 1474\end{verbatim} 1475\end{hol} 1476% 1477Ora dobbiamo scegliere la posizione di argomento da misurare e 1478invocare \ml{WF\_REL\_TAC}: 1479\begin{session} 1480\begin{verbatim} 1481 - e (WF_REL_TAC `measure FST`); 1482 OK.. 1483 1 subgoal: 1484 > val it = 1485 !v2 n. n MOD SUC v2 < SUC v2 1486\end{verbatim} 1487\end{session} 1488% 1489Questo goal � facile da dimostrare con alcuni semplici fatti aritmetici. 1490 1491\paragraph{Funzioni di Ponderazione} 1492 1493A volte, si ha bisogno di una funzione di misura che sia essa stessa ricorsiva. Per 1494esempio, si consideri un tipo di alberi binari e una funzione che 1495linearizza gli alberi. L'algoritmo funziona ruotando l'albero fino a quando 1496ottiene un \holtxt{Leaf} nel ramo sinistro, poi esegue una ricorsione nel ramo 1497destro. Alla fine dell'esecuzione l'albero � stato linearizzato. 1498\setcounter{sessioncount}{0} 1499\begin{session} 1500\begin{verbatim} 1501 - Hol_datatype 1502 `btree = Leaf 1503 | Brh of btree => btree`; 1504 1505 - val Unbal_defn = 1506 Hol_defn "Unbal" 1507 `(Unbal Leaf = Leaf) 1508 /\ (Unbal (Brh Leaf bt) = Brh Leaf (Unbal bt)) 1509 /\ (Unbal (Brh (Brh bt1 bt2) bt) = Unbal (Brh bt1 (Brh bt2 bt)))`; 1510 1511 - Defn.tgoal Unbal_defn; 1512 1513 > val it = 1514 Proof manager status: 1 proof. 1515 1. Incomplete: 1516 Initial goal: 1517 ?R. WF R /\ 1518 (!bt. R bt (Brh Leaf bt)) /\ 1519 !bt bt2 bt1. R (Brh bt1 (Brh bt2 bt)) (Brh (Brh bt1 bt2) bt) 1520\end{verbatim} 1521\end{session} 1522% 1523Dal momento che la dimensione dell'albero non � modificata nell'ultima clausola nella 1524definizione di \holtxt{Unbal}, una semplice misura di dimensione non funziona. Piuttosto, 1525possiamo assegnare dei pesi ai nodi nell'albero tali che le chiamate ricorsive di 1526\holtxt{Unbal} diminuiscono il peso totale in ogni case. Una tale assegnazione � 1527% 1528\begin{session} 1529\begin{verbatim} 1530 Define 1531 `(Weight (Leaf) = 0) /\ 1532 (Weight (Brh x y) = (2 * Weight x) + (Weight y) + 1)` 1533\end{verbatim} 1534\end{session} 1535% 1536Ora possiamo invocare \ml{WF\_REL\_TAC}: 1537% 1538\begin{session} 1539\begin{verbatim} 1540 e (WF_REL_TAC `measure Weight`); 1541 OK.. 1542 1543 2 subgoals: 1544 > val it = 1545 !bt. Weight bt < Weight (Brh Leaf bt) 1546 1547 !bt bt2 bt1. 1548 Weight (Brh bt1 (Brh bt2 bt)) < Weight (Brh (Brh bt1 bt2) bt) 1549\end{verbatim} 1550\end{session} 1551% 1552Entrambi questi goal sono piuttosto facili da dimostrare. 1553% 1554Le tecniche di `ponderazione' di nodi in un datatype al fine di dimostrare 1555la terminazione vanno anche sotto il nome di \emph{interpretazione polinomiale}. Bisogna 1556ammettere che trovare la ponderazione corretta per una dimostrazione 1557di terminazione � pi� un'arte che una scienza. Tipicamente, si fa una congettura e 1558si prova la dimostrazione di terminazione per vedere se funziona. 1559 1560\paragraph{Combinazioni Lessicografiche} 1561 1562Saltuariamente, c'� una combinazione di fattori che complica 1563l'argomento di terminazione. Per esempio, la seguente specifica 1564descrive un ingenuo algoritmo di pattern matching su stringhe (qui 1565rappresentate come liste). La funzione prende quattro argomenti: il primo, $p$, 1566� il rimanente del pattern da matchare. Il secondo, 1567$\mathit{rst}$, � il rimanente della stringa che viene cercata. Il terzo 1568argomento, $p_0$, mantiene il pattern originale da matchare. 1569Il quarto argomento, $s$, � la stringa che viene cercata. 1570% 1571\setcounter{sessioncount}{0} 1572\begin{session} 1573\begin{verbatim} 1574 val match_defn = 1575 Hol_defn "match" 1576 `(match [] __ __ __ = T) /\ 1577 (match __ [] __ __ = F) /\ 1578 (match (a::pp) (b::ss) p0 s = 1579 if a=b then match pp ss p0 s 1580 else 1581 if NULL(s) then F 1582 else 1583 match p0 (TL s) p0 (TL s))`; 1584 1585 - val Match = Define `Match pat str = match pat str pat str`; 1586\end{verbatim} 1587\end{session} 1588% 1589La prima clausola della definizione afferma che se $p$ si esaurisce, allora � stato 1590trovato un match; la funzione restituisce \holtxt{T}. La seconda clausola rappresenta il caso 1591dove $s$ � esaurito ma $p$ no, in questo caso la funzione restituisce 1592\holtxt{F}. Il caso rimanente � quando c'� pi� ricerca da fare; la funzione 1593controlla se la testa del pattern $p$ � la stessa della testa di 1594$\mathit{rst}$. Se s�, allora la ricerca procede ricorsivamente, usando la 1595coda di $p$ e la coda di $\mathit{rst}$. Se no, questo significa che $p$ ha 1596fallito il match, cos� l'algoritmo avanza di un carattere in avanti in 1597$\mathit{s}$ e inizia il matching dall'inizio di $p_0$. Se 1598$\mathit{s}$ � vuoto allora, comunque, restituisce \holtxt{F}. Si noti che 1599$\mathit{rst}$ e $s$ rappresentano entrambi la stringa da 1600cercare: $\mathit{rst}$ � una versione `locale` di $s$: eseguiamo una ricorsione in 1601$\mathit{rst}$ fino a quando ci sono dei match con il pattern $p$. Tuttavia, 1602se la ricerca alla fine fallisce, allora $s$, che `ricorda` dove la ricerca 1603� iniziata, � usata per riavviare la ricerca. 1604 1605Questo per quanto riguarda il comportamento della funzione. Perch� termina? Ci 1606sono due chiamate ricorsive. La prima chiamata riduce la dimensione di $p$ e $\mathit{rst}$, e 1607lascia l'altro argomento invariato. La seconda chiamata pu� accrescere la 1608dimensione di $p$ e $\mathit{rst}$, ma riduce la dimensione di $s$. Questa � una classica situazione 1609in cui usare un ordine lessicografico: alcuni argomenti alla funzione sono ridotti in 1610alcune chiamate ricorsive, e altri sono ridotti in altre chiamate ricorsive. 1611Si ricordi che \holtxt{LEX} � un operatore infisso, definito in \ml{pairTheory} come segue: 1612% 1613\begin{hol} 1614\begin{verbatim} 1615 |- LEX R1 R2 = \(x,y) (p,q). R1 x p \/ ((x=p) /\ R2 y q) 1616\end{verbatim} 1617\end{hol} 1618% 1619Nella seconda chiamata ricorsiva, la lunghezza di \holtxt{s} � ridotta, e nella 1620prima rimane uguale. Questo spinge ad avere la lunghezza della 1621$s$ come il primo componente della combinazione 1622lessicografica, e la lunghezza di $\mathit{rst}$ come il secondo 1623componente. Formalmente, vogliamo mappare dalla quadrupla degli 1624argomenti in una combinazione lessicografica di relazioni. 1625Questo � permesso da \holtxt{inv\_image} di \ml{relationTheory}: 1626% 1627\begin{hol} 1628\begin{verbatim} 1629 |- inv_image R f = \x y. R (f x) (f y) 1630\end{verbatim} 1631\end{hol} 1632% 1633La relazione desiderata mappa dalla quadrupla degli argomenti in una coppia 1634di numeri $(m,n)$, dove $m$ � la lunghezza del quarto argomento, e 1635$n$ � la lunghezza del secondo argomento. Queste lunghezze sono poi 1636confrontate dal punto di vista lessicografico rispetto a minore-di ($<$). 1637\begin{session} 1638\begin{verbatim} 1639 Defn.tgoal match_defn; 1640 1641 - e (WF_REL_TAC `inv_image($< LEX $<) (\(w,x,y,z). (LENGTH z,LENGTH x))`); 1642 OK.. 1643 2 subgoals: 1644 > val it = 1645 !s ss a b. 1646 (a=b) ==> LENGTH s < LENGTH s \/ LENGTH ss < LENGTH (b::ss) 1647 1648 !ss s a b. 1649 ~(a = b) /\ ~NULL s ==> 1650 LENGTH (TL s) < LENGTH s \/ 1651 (LENGTH (TL s) = LENGTH s) /\ LENGTH (TL s) < LENGTH (b::ss) 1652\end{verbatim} 1653\end{session} 1654% 1655Il primo subgoal ha bisogno di un case-split su \holtxt{s} prima di essere dimostrato per 1656riscritture, e il secondo � anch'esso facile da dimostrare per riscrittura. 1657 1658\subsubsection{Come sono sintetizzate le condizioni di terminazione} 1659 1660\index{regole di congruenza!nelle analisi di terminazione|(} 1661A volte � importante comprendere, almeno in parte, come 1662\ml{Hol\_defn} costruisce i vincoli di terminazione. In alcuni casi, � 1663persino necessario che gli utenti influenzino questo processo al fine di avere estratti 1664dei vincoli di terminazione corretti. Il processo � guidato dai cosiddetti 1665\emph{teoremi di congruenza} per particolari vincoli \HOL{}. 1666Per esempio, si consideri la seguente definizione ricorsiva di fattoriale: 1667% 1668\begin{hol} 1669\begin{verbatim} 1670 fact n = if n=0 then 1 else n * fact (n-1) 1671\end{verbatim} 1672\end{hol} 1673% 1674In assenza di una conoscenza di come il costrutto `if-then-else` 1675influisce il \emph{contesto} delle chiamate ricorsive, \ml{Hol\_defn} 1676estrarrebbe i vincoli di terminazione: 1677% 1678\begin{hol} 1679\begin{verbatim} 1680 0. WF R 1681 1. !n. R (n - 1) n 1682\end{verbatim} 1683\end{hol} 1684% 1685che non sono dimostrabili, perch� il \emph{contesto} delle chiamate ricorsive non � 1686stato preso in considerazione. Questo esempio di fatto non � un problema per HOL, 1687dal momento che il seguente teorema di congruenza � conosciuto da \ml{Hol\_defn}: 1688% 1689\begin{hol} 1690\begin{verbatim} 1691 |- !b b' x x' y y'. 1692 (b = b') /\ 1693 (b' ==> (x = x')) /\ 1694 (~b' ==> (y = y')) ==> 1695 ((if b then x else y) = (if b' then x' else y')) 1696\end{verbatim} 1697\end{hol} 1698% 1699Questo teorema � compreso da \ml{Hol\_defn} come una sequenza ordinata 1700di istruzioni da seguire quando l'estrattore di condizioni di terminazione 1701incontra un `if-then-else`. Il teorema � letto come segue: quando 1702un'istanza `\texttt{if} $B$ \texttt{then} $X$ \texttt{else} $Y$` � 1703incontrata mentre l'estrattore passa attraverso la definizione di funzione, 1704fa ci� che segue. 1705\begin{enumerate} 1706 1707\item Traversa $B$ ed estrae le condizioni di terminazione 1708 $\mathit{TCs}(B)$ da ogni chiamata ricorsiva al suo interno. 1709 Questo restituisce un teorema $\mathit{TCs}(B) \vdash B = B'$. 1710 1711\item Assume $B'$ ed estrae le condizioni di terminazione da ogni 1712 chiamata ricorsiva in $X$. Questo restituisce un teorema 1713 $\mathit{TCs}(X) \vdash X = X'$. 1714 1715\item Assume $\neg B'$ ed estrae le condizioni di terminazione da ogni 1716 chiamata ricorsiva in $Y$. Questo restituisce un teorema 1717 $\mathit{TCs}(Y) \vdash Y = Y'$. 1718 1719\item Ragionando in modo equazionale con (1), (2), e (3), deriva il teorema 1720\[\mathit{TCs}(B) \cup \mathit{TCs}(X) \cup \mathit{TCs}(Y) 1721 \vdash 1722 (\mathtt{if}\ B\ \mathtt{then}\ X\ \mathtt{else}\ Y) = 1723 (\mathtt{if}\ B'\ \mathtt{then}\ X'\ \mathtt{else}\ Y') 1724\] 1725\item Sostituisce \texttt{if} $B$ \texttt{then} $X$ \texttt{else} $Y$ con 1726\texttt{if} $B'$ \texttt{then} $X'$ \texttt{else} $Y'$. 1727 1728\end{enumerate} 1729 1730 1731Le condizioni di terminazione sono accumulate fino a quando 1732il processo di terminazione non finisce, ed appaiono come ipotesi nel risultato 1733finale. Cos� le condizioni di terminazione estratte per \holtxt{fact} sono 1734% 1735\begin{hol} 1736\begin{verbatim} 1737 0. WF R 1738 1. !n. ~(n = 0) ==> R (n - 1) n 1739\end{verbatim} 1740\end{hol} 1741% 1742e sono facili da dimostrare. La nozione di \emph{contesto} di una chiamata ricorsiva 1743� definita dall'insieme di regole di congruenza usate nell'estrazione delle condizioni 1744di terminazione. Questo insieme si pu� ottenere invocando \holtxt{DefnBase.read\_congs}, 1745e manipolare con \holtxt{DefnBase.add\_cong}, 1746\holtxt{DefnBase.drop\_cong} e \holtxt{DefnBase.export\_cong}. 1747Le funzioni `add' e `drop' influenzano solo lo stato attuale del database di congruenza; per contro, la funzione `export' fornisce un modo per le teorie di specificare che un particolare teorema dovrebbe essere aggiunto al database di congruenza in tutte le teorie discendenti. 1748\index{regole di congruenza!nelle analisi di terminazione|(} 1749 1750 1751 1752 1753\paragraph{Ricorsione di Ordine Superiore e Regole di Congruenza} 1754 1755Una ricorsione di `ordine superiore' � una in cui una funzione di ordine superiore � 1756usata per applicare la funzione ricorsiva agli argomenti. Al fine di 1757dimostrare le condizioni di terminazione corrette per una tale ricorsione, 1758le regole di congruenza per la funzione di ordine superiore devono essere conosciute 1759dal meccanismo di estrazione delle condizioni di terminazione. Le regole di congrueza per 1760funzioni di ordine superiore comuni, ad esempio \holtxt{MAP}, \holtxt{EVERY}, and 1761\holtxt{EXISTS} per le liste, sono gi� conosciute dal 1762meccanismo. Tuttavia, a volte, di deve dimostrare ed installare manualmente un 1763teorema di congruenza per una nuova funzione di ordine superiore definita dall'utente. 1764 1765Per esempio, supponiamo di definire una funzione di ordine superiore \holtxt{SIGMA} per 1766sommare i risultati di una funzione in una lista. 1767% 1768\setcounter{sessioncount}{0} 1769\begin{session} 1770\begin{verbatim} 1771 Define `(SIGMA f [] = 0) /\ 1772 (SIGMA f (h::t) = f h + SIGMA f t)`; 1773\end{verbatim} 1774\end{session} 1775% 1776Usiamo poi \holtxt{SIGMA} nella definizione di una funzione per 1777sommare i risultati di una funzione in un albero 1778arbitrariamente (finitamente) ramificato. 1779% 1780\begin{session} 1781\begin{verbatim} 1782 Hol_datatype `ltree = Node of 'a => ltree list`; 1783 1784 Defn.Hol_defn 1785 "ltree_sigma" 1786 `ltree_sigma f (Node v tl) = f v + SIGMA (ltree_sigma f) tl`; 1787\end{verbatim} 1788\end{session} 1789% 1790In questa definizione, \holtxt{SIGMA} � applicato a un'applicazione parziale 1791\holtxt{(ltree\_sigma f)} della funzione da definire. Una tale situazione 1792� chiamata una \emph{ricorsione di ordine superiore}. Dal momento che la chiamata ricorsiva di 1793\holtxt{ltree\_sigma} non � applicata in modo completo, bisogna fare degli sforzi 1794speciali per estrarre le condizioni di terminazione corrette. Altrimenti, 1795risulta la seguente infelice situazione: 1796% 1797\begin{session} 1798\begin{verbatim} 1799 HOL function definition (recursive) 1800 1801 Equation(s) : 1802 [..] |- ltree_sigma f (Node v tl) 1803 = f v + SIGMA (\a. ltree_sigma f a) tl 1804 1805 Induction : 1806 [..] |- !P. (!f v tl. (!a. P f a) ==> P f (Node v tl)) ==> !v v1. P v v1 1807 1808 Termination conditions : 1809 0. WF R 1810 1. !tl v f a. R (f,a) (f,Node v tl) : defn 1811\end{verbatim} 1812\end{session} 1813% 1814\index{regole di congruenza!nelle analisi di terminazione|(} 1815Le condizioni di terminazione per \holtxt{ltree\_sigma} sembrano 1816richiedere di trovare una relazione benfondata \holtxt{R} tale che la coppia 1817\holtxt{(f,a)} � \holtxt{R}-minore di 1818\holtxt{(f, Node v tl)}. Tuttavia, questo � un compito senza speranza, dal momento che non c'� alcuna 1819relazione tra \holtxt{a} e \holtxt{Node v tl}, oltre al fatto 1820che entrambi sono \holtxt{ltree}. L'estrattore di condizioni di terminazione 1821non ha funzionato in modo appropriato, perch� non conosceva una regola di congruenza 1822per \holtxt{SIGMA}. Una tale teorema di congruenza � il seguente: 1823% 1824\begin{hol} 1825\begin{verbatim} 1826 SIGMA_CONG = 1827 |- !l1 l2 f g. 1828 (l1=l2) /\ (!x. MEM x l2 ==> (f x = g x)) ==> 1829 (SIGMA f l1 = SIGMA g l2) 1830\end{verbatim} 1831\end{hol} 1832% 1833Una volta che a \ml{Hol\_defn} � stato fornito questo teorema, attraverso le funzioni \ml{add\_cong} o \ml{export\_cong} di \ml{DefnBase}, le condizioni di terminazione estratte per la definizione sono ora dimostrabili, dal momento che \holtxt{a} � un sottotermine proprio di \holtxt{Node v tl}. 1834% 1835\begin{session} 1836\begin{verbatim} 1837 val _ = DefnBase.add_cong SIGMA_CONG; 1838 1839 Defn.Hol_defn 1840 "ltree_sigma" 1841 `ltree_sigma f (Node v tl) = f v + SIGMA (ltree_sigma f) tl`; 1842 1843 > val it = 1844 HOL function definition (recursive) 1845 1846 Equation(s) : ... (* as before *) 1847 Induction : ... (* as before *) 1848 1849 Termination conditions : 1850 0. WF R 1851 1. !v f tl a. MEM a tl ==> R (f,a) (f,Node v tl) 1852\end{verbatim} 1853\end{session} 1854 1855\subsection{Schemi di Ricorsione} 1856 1857Nella logica di ordine superiore, possono essere definiti pattern molto generali di ricorsione, conosciuti come 1858\emph{schemi di ricorsione} o a volte \emph{schemi di programma}. 1859Un esempio � il seguente: 1860% 1861\[ 1862 \konst{linRec} (x) = 1863 \itelse{d(x)}{e(x)}{f(\konst{linRec}(g\; x))} 1864\] 1865% 1866In questa specifica, le variabili $d$, $e$, $f$, e $g$ sono 1867funzioni, che, quando istanziate in modi differenti, permettono a 1868\konst{linRec} di implementare funzioni ricorsive differenti. In questo, 1869\konst{linRec} � come molte altre funzioni di ordine superiore. Tuttavia, 1870si noti che se $d(x) = \konst{F}$, $f(x) = x+1$, e 1871$g(x) = x$, allora l'istanziazione risultante di 1872\konst{linRec} potrebbe essere usata per ottenere una contraddizione: 1873% 1874\[ 1875 \konst{linRec} (x) = \konst{linRec}(x) + 1 1876\] 1877% 1878Questo, comunque, non � derivabile in \HOL{}, perch� gli schemi di ricorsione 1879sono definiti istanziando il teorema di ricorsione benfondata, e 1880pertanto sorgono certi vincoli astratti di terminazione che 1881devono essere soddisfatti prima che le equazioni di ricorsione possano essere usati senza 1882restrizioni. L'entrypoint per definire uno schema � 1883\ml{TotalDefn.DefineSchema}. Nell'esempio \konst{linRec} 1884si comporta nel modo seguente (si noti che le variabili schematiche dovrebbero 1885occorrere solo sul lato destro della definizione quando si fa 1886la definizione di uno schema): 1887% 1888\setcounter{sessioncount}{0} 1889\begin{session} 1890\begin{verbatim} 1891 - TotalDefn.DefineSchema 1892 `linRec (x:'a) = if d(x) then e(x) else f(linRec(g x))`; 1893 1894 <<HOL message: Definition is schematic in the following variables: 1895 "d", "e", "f", "g">> 1896 1897 Equations stored under "linRec_def". 1898 Induction stored under "linRec_ind". 1899 > val it = 1900 [..] 1901 |- linRec d e f g x = if d x then e x else f (linRec d e f g (g x)) 1902\end{verbatim} 1903\end{session} 1904% 1905Le ipotesi del teorema restituito soddisfano i vincoli astratti 1906di terminazione. Un teorema d'induzione vincolato in modo simile � 1907anche archiviato nel segmento attuale di teoria. 1908% 1909\begin{session} 1910\begin{verbatim} 1911 hyp it; 1912 > val it = [``!x. ~d x ==> R (g x) x``, ``WF R``] : term list 1913\end{verbatim} 1914\end{session} 1915% 1916Questi vincoli sono astratti, dal momento che pongono dei requisiti di terminazione 1917su variabili che non sono state ancora istanziate. Una volta che sono trovate 1918istanziazioni per le variabili, i vincoli possono poi essere eliminati 1919trovando un'adeguata relazione benfondata per \holtxt{R} e poi 1920dimostrando gli altri vincoli. 1921 1922\section{Relazioni Induttive} 1923\index{relazioni induttive|(} 1924 1925\index{Hol_reln, definire relazioni induttive@\ml{Hol\_reln}, definire relazioni induttive} 1926\index{relazioni induttive!Hol_reln (funzione ML)@\ml{Hol\_reln} (funzione ML)} 1927Le definizioni induttive sono fatte con la funzione \ml{Hol\_reln}, che si trova 1928nella struttura \ml{bossLib}, e le definizioni e i teoremi 1929risultanti sono gestiti con funzioni definite nella libreria 1930\ml{IndDefLib}. La funzione \ml{Hol\_reln} prende una 1931term quotation come input e tenta di definire le relazioni li 1932specificate. La term quotation di input deve essere parsata a un termine che 1933si conforma alla seguente grammatica: 1934\newcommand{\nonterm}[1]{\ensuremath{\langle\mathit{#1}\rangle}} 1935\begin{eqnarray*} 1936 \nonterm{formatoDiInput} &::=& \nonterm{clausola} \;\holtxt{/\bk}\; \nonterm{formatoDiInput} \;\;|\;\; \nonterm{clausola}\\ 1937 \nonterm{clausola} &::=& (\holtxt{!}x_1 \dots 1938 x_n. \;\;\nonterm{ipotesi} \;\holtxt{==>} 1939 \;\nonterm{conclusione})\\ 1940 &|& (\holtxt{!}x_1\dots x_n.\;\;\nonterm{conclusione})\\ 1941 \nonterm{conclusione} &::=& \nonterm{con} \;\mathit{sv_1}\; \mathit{sv_2} \dots\\ 1942 \nonterm{ipotesi} &::=& \mbox{qualsiasi termine}\\ 1943 \nonterm{con} &::=& \mbox{una nuova costante di relazione} 1944\end{eqnarray*} 1945I termini (opzionali) $\mathit{sv}_i$ che appaiono dopo il nome di una costante 1946sono le cosiddette ``variabili schematiche''. Le stesse variabili devono sempre 1947seguire tutte le costanti nuove in tutta la definizione. Queste variabili 1948e i nomi delle costanti-to-be non devono essere quantificate in 1949ciascuna {\nonterm{clausola}}. Una {\nonterm{clausola}} non dovrebbe avere 1950altre variabili libere. Qualunque variabile che occorra sar� quantificata universalmente come parte 1951del processo di definizione, e sar� emesso un messaggio di warning. 1952(I quantificatori universali alla testa della clausola possono essere usati per legare 1953le variabili libere, ma � anche ammissibile usare la quantificazione 1954esistenziale nelle ipotesi. Se una clausola non ha variabili libere, 1955� ammissibili non avere alcuna quantificazione universale.) 1956 1957Un'invocazione di successo di \ml{Hol\_reln} restituisce tre teoremi 1958$(\mathit{rules},\mathit{ind},\mathit{cases})$. Ognuno � anche archiviato nel 1959segmento di teoria attuale. 1960\begin{itemize} 1961\item $\mathit{rules}$ � una congiunzione di implicazioni 1962 che sar� la stessa della term quotation di input; il teorema � 1963 salvato sotto il nome \ml{<stem>\_rules}, dove \ml{<stem>} � il nome della 1964 prima relazione definita dalla funzione. 1965\item $\mathit{ind}$ � il principio d'induzione per le relazioni, 1966 salvato sotto il nome \ml{<stem>\_ind}. 1967\item $\mathit{cases}$ � il cosiddetto teorema dei `casi' o di `inversione' 1968 per le relazioni, salvato sotto il nome \ml{<stem>\_cases}. Un teorema 1969 dei casi � della forma 1970% 1971\begin{verbatim} 1972 (!a0 .. an. R1 a0 .. an = <Prima regola di possibilit� di R1> \/ 1973 <Seconda regola di possibilit� di R1> \/ ...) 1974 /\ 1975 (!a0 .. am. R2 a0 .. am = <Prima regola di possibilit� di R2> \/ 1976 <Seconda regola di possibilit� di R2> \/ ...) 1977 /\ 1978 ... 1979\end{verbatim} 1980% 1981ed � usato per decomporre un elemento nella relazione nei 1982possibili modi di ottenerlo dalle regole. 1983\end{itemize} 1984 1985\index{xHol_reln, definire relazioni induttive@\ml{xHol\_reln}, definire relazioni induttive} 1986\index{relazioni induttive!xHol_reln (ML function)@\ml{xHol\_reln} (funzione ML)} 1987Se lo ``stem'' della prima costante definita in un insieme di clausole � tale che i binding \ML{} risultanti in un file di teoria esportato risulteranno in un codice \ML{} non legale, allora si dovrebbe usare la funzione \ml{xHol\_reln}. 1988La funzione \ml{xHol\_reln} � analoga alla funzione \ml{xDefine} per definire funzioni ricorsive (si veda la Sezione~\ref{TFL}). 1989 1990\paragraph{Principi d'Induzione Completa} 1991Le cosiddette versioni ``complete'' dei principi d'induzione (in cui le istanze della relazione da definire appaiono come ipotesi extra), sono dimostrate automaticamente quando � fatta una definizione con \ml{Hol\_reln}. Il principio d'induzione completa per una relazione � usato quando � usata la tattica \ml{Induct\_on}. 1992 1993\paragraph{Aggiungere Operatori Monotoni} 1994\index{relazioni induttive!operatori monotoni per} 1995Nuove costanti possono occorrere ricorsivamente all'interno delle ipotesi delle regole, purch� 1996si possa dimostrare che le regole rimangono monotone rispetto alle 1997nuove costanti. \ml{Hol\_reln} tenter� di dimostrare automaticamente tali 1998risultati di monotonicit�, usando un insieme di teoremi mantenuti in una reference 1999\ml{IndDefLib.the\_monoset}. I teoremi di monotonicit� devono essere della forma 2000\[ 2001\mathit{cond}_1 \land \cdots \land \mathit{cond}_m \Rightarrow 2002(\mathit{Op}\;\mathit{arg}_1 \dots \mathit{arg}_n \Rightarrow 2003\mathit{Op}\;\mathit{arg}'_1 \dots \mathit{arg}'_n) 2004\] 2005dove ciascun termine $\mathit{arg}$ e $\mathit{arg}'$ deve avere una variabile, 2006e dove ci devono essere tanti termini $\mathit{cond}_i$ quanti sono gli 2007argomenti a $\mathit{Op}$ che variano. Ciascun $\mathit{cond}_i$ deve essere 2008della forma \[ \forall \vec{v}. \;\mathit{arg}\;\vec{v} \Rightarrow 2009\mathit{arg}'\;\vec{v} 2010\] 2011dove il vettore di variabili $\vec{v}$ pu� essere vuoto, e dove i 2012$\mathit{arg}$ e $\mathit{arg}'$ possono essere di fatto invertiti (come nella 2013regola per la negazione). 2014 2015Per esempio, la regola di monotonicit� per la congiunzione � 2016\[ 2017(P \Rightarrow P') \land (Q \Rightarrow Q') \Rightarrow (P \land Q 2018\Rightarrow P' \land Q') 2019\] 2020La regola di monotonicit� per l'operatore \holtxt{EVERY} nella teoria delle 2021liste (si veda la Sezione~\ref{avra_list}), � 2022\[ 2023(\forall x. \;P(x) \Rightarrow Q(x)) \Rightarrow 2024(\holtxt{EVERY}\;P\;\ell \Rightarrow \holtxt{EVERY}\;Q\;\ell) 2025\] 2026Con un risultato di monotonicit� disponibile per un operatore come 2027\holtxt{EVERY}, � poi possibile scrivere definizioni induttive 2028dove le ipotesi includono una menzione della nuova relazione come argomenti agli 2029operatori dati. 2030 2031\index{export_mono (funzione ML)@\ml{export\_mono} (funzione \ML{})} 2032I risultati di monotonicit� che l'utente deriva possono essere archiviati nella variabile 2033globale \ml{the\_monoset} usando la funzione \ml{export\_mono}. 2034Questa funzione prende una stringa che nomina un teorema nel segmento di teoria 2035attuale, e aggiunge quel teorema ai teoremi di monotonicit� 2036immediatamente, e in un tal modo che questa situazione si otterr� anche quando 2037la teoria attuale � successivamente ricaricata. 2038 2039\paragraph{Esempi} 2040 2041Un semplice esempio di definizione di due relazioni mutuamente ricorsive � 2042il seguente: 2043% 2044\setcounter{sessioncount}{0} 2045\begin{session} 2046\begin{verbatim} 2047 Hol_reln 2048 `EVEN 0 /\ 2049 (!n. ODD n ==> EVEN (n + 1)) /\ 2050 (!n. EVEN n ==> ODD (n + 1))`; 2051\end{verbatim} 2052\end{session} 2053% 2054Il risultato sono tre teoremi 2055% 2056\begin{session} 2057\begin{verbatim} 2058 > val it = 2059 (|- EVEN 0 /\ 2060 (!n. ODD n ==> EVEN (n + 1)) /\ 2061 (!n. EVEN n ==> ODD (n + 1)), 2062 2063 |- !EVEN' ODD'. 2064 EVEN' 0 /\ 2065 (!n. ODD' n ==> EVEN' (n + 1)) /\ 2066 (!n. EVEN' n ==> ODD' (n + 1)) 2067 ==> 2068 (!a0. EVEN a0 ==> EVEN' a0) /\ 2069 (!a1. ODD a1 ==> ODD' a1), 2070 2071 |- (!a0. EVEN a0 = (a0 = 0) \/ 2072 ?n. (a0 = n + 1) /\ ODD n) /\ 2073 (!a1. ODD a1 = ?n. (a1 = n + 1) /\ EVEN n) 2074 ) : thm * thm * thm 2075\end{verbatim} 2076\end{session} 2077% 2078Il prossimo esempio mostra come definire induttivamente la chiusura riflessiva e 2079transitiva di una relazione $R$. Si noti che \holtxt{R}, come una 2080variabile schematica, non � quantificata nelle regole. Questo � 2081appropriato perch� � \holtxt{RTC R} che ha la caratterizzazione 2082induttiva, \holtxt{RTC} di per s�. 2083% 2084\begin{session} 2085\begin{verbatim} 2086 - Hol_reln `(!x. RTC R x x) /\ 2087 (!x z. (?y. R x y /\ RTC R y z) ==> RTC R x z)`; 2088 2089 > val it = 2090 (|- !R. (!x. RTC R x x) /\ 2091 !x z. (?y. R x y /\ RTC R y z) ==> RTC R x z, 2092 2093 |- !R RTC'. 2094 (!x. RTC' x x) /\ 2095 (!x z. (?y. R x y /\ RTC' y z) ==> RTC' x z) 2096 ==> 2097 (!a0 a1. RTC R a0 a1 ==> RTC' a0 a1), 2098 2099 |- !R a0 a1. RTC R a0 a1 = (a1 = a0) \/ ?y. R a0 y /\ RTC R y a1 2100 ) : thm * thm * thm 2101\end{verbatim} 2102\end{session} 2103% 2104La funzione \ml{Hol\_reln} pu� essere usata per definire relazioni multiple, 2105come nella definizione di \holtxt{EVEN} e \holtxt{ODD}. Le relazioni 2106possono essere mutuamente ricorsive o meno. Le clausole per ciascuna relazione 2107non hanno bisogno di essere contigue. 2108 2109\subsection{Dimostrazioni con Relazioni Induttive} 2110\index{relazioni induttive!eseguire dimostrazioni} 2111 2112Il teorema ``regole'' di una definizione induttiva fornisce un modo diretto di dimostrare argomenti che appartengono a una relazione. 2113Se ci si trova di fronte a un goal della forma \holtxt{R~x~y}, si potrebbe fare progressi eseguendo una \ml{MATCH\_MP\_TAC} (o magari, una \ml{HO\_MATCH\_MP\_TAC}) con una delle implicazioni nel teorema ``regole''. 2114 2115Il teorema ``casi'' pu� essere usato per lo stesso scopo perch� � un'uguaglianza, della forma generale \holtxt{R~x~y~$\iff$\dots}. 2116Dal momento che il lato destro di questo teorema includer� spesso altre occorrenze della relazione, non � in generale sicuro riscrivere semplicemente con esso. 2117\index{SimpLHS@\ml{SimpLHS}}\index{SimpRHS@\ml{SimpRHS}} 2118\index{Once (controllo delle applicazioni di riscrittura)@\ml{Once} (controllo delle applicazioni di riscrittura)} 2119Qui possono essere usate le direttive di controllo-di-riscrittura \ml{Once}, \ml{SimpLHS} e \ml{SimpRHS}. 2120\index{FULL_SIMP_TAC@\ml{FULL\_SIMP\_TAC}} 2121Inoltre, il teorema ``casi'' pu� essere usato come una forma di eliminazione: se si ha un'assunzione della forma \holtxt{R~x~y}, riscrivere questo (magari con \ml{FULL\_SIMP\_TAC} se il termine occorre nelle assunzioni del goal) nei possibili modi in cui pu� essere avvenuto � spesso un buon approccio. 2122 2123Le relazioni induttive naturalmente supportano anche dimostrazioni per induzione. 2124Poich� una relazione induttiva � la relazione minima che soddisfa le regole date, si pu� usare l'induzione per mostrare goal della forma 2125\begin{alltt} 2126 \(\forall\)x y. R x y \(\Rightarrow\) P 2127\end{alltt} 2128dove \holtxt{P} � un predicato arbitrario che probabilmente include riferimenti alle variabili \holtxt{x} e \holtxt{y}. 2129 2130L'approccio di basso livello a goal di questa forma � di applicare 2131\begin{verbatim} 2132 HO_MATCH_MP_TAC R_ind 2133\end{verbatim} 2134\index{Induct_on (tattica d'induzione ML)@\ml{Induct\_on} (tattica d'induzione \ML{})} 2135Un approccio leggermente di pi� alto livello � di usare la tattica \ml{Induct\_on}. 2136(Questa tattica � anche usata per eseguire induzioni strutturali su tipi di dato algebrici; si veda la Sezione~\ref{sec:bossLib}.) 2137Quando si esegue una regola d'induzione, la quotation passata a \ml{Induct\_on} dovrebbe essere della costante usata. 2138Per questioni estetiche, la costante pu� anche essere applicata a degli argomenti. 2139Cos�, si pu� scrivere 2140\begin{verbatim} 2141 Induct_on `R` 2142\end{verbatim} 2143o 2144\begin{verbatim} 2145 Induct_on `R x y` 2146\end{verbatim} 2147e l'effetto sar� lo stesso. 2148\index{relazioni induttive|)} 2149 2150 2151%%% Local Variables: 2152%%% mode: latex 2153%%% mode: visual-line 2154%%% TeX-master: "description" 2155%%% End: 2156