Il sistema di tipi
Questo capitolo espone la parte fondamentale di questo studio. Verrà inizialmente data una spiegazione di cos’è un sistema di tipi e quali sono i suoi scopi. Si procederà dunque alla esposizione dei tipi, dei giudizi e delle regole di tipo.
3.1
Premesse
Come accennato nell’introduzione un sistema di tipi ha come obiettivi principali quello di prevenire il verificarsi di errori durante l’esecuzione di un programma e descrivere il tipo del risultato della query.
Consideriamo ad esempio una variabile usata in un programma. Nella sua dichiarazione generalmente è associata ad un tipo. Ciò indica che durante l’esecuzione la variabile può assumere uno dei valori facenti parte del dominio di quel tipo tipo. Per esempio una variabile di tipo Bool potrà assumere valori dell’insieme Dom(Bool) = {true, false}. Un sistema di tipi si assicura che ciò si verifichi, cioè che la variabile non assuma valori non coerenti con il suo tipo.
Un linguaggio in cui le variabili hanno associato un tipo sono chiamati linguaggi tipizzati. Un linguaggio non tipizzato non pone questi vincoli per cui vi è un tipo universale per tutte le variabili.
Il sistema di tipi è un componente del linguaggio tipizzato che per-mette di tener traccia dei tipi delle variabili nonchè delle espressioni del
programma. Un programma è ben formato quando non si verifica nessun errore.
Gli errori in questione li possiamo classificare in due categorie. Gli errori che interrompono il flusso di esecuzione e quelli che invece portano il programma ad avere un comportamento arbitrario. Un esempio dei primi è quello degli operatori matematici in cui ci si aspetta che il tipo degli argomenti sia numerico, e vogliamo generare un errore quando viene passata per esempio una stringa interrompendo l’esecuzione. Per i secondi un esempio è quello di accedere ad un indirizzo di cui non si hanno i permessi oppure accedere ad un puntatore deallocato.
I linguaggi tipizzati possono verificare se un programma è ben formato oppure no tramite un controllo statico chiamato typechecking che consiste in un algoritmo (typechecker) che userà il sistema di tipi per eseguire questo controllo.
3.2
Assunzioni OWA
/CWA
Le basi di conoscenza usano in genere un’assunzione a mondo aperto (Open World Assumption, OWA) in base alla quale tutto ciò che è specifi-cato è vero mentre quello non contenuto o è vero o è falso. Questa è anche la semantica di RDF.
Invece le basi di dati normalmente sono interpretate usando l’approccio a mondo chiuso (Closed World Assumption, CWA) in cui si considerano vere le informazioni presenti nella base di dati e false quelle che non lo sono.
Per chiarire il concetto facciamo un esempio. Consideriamo le due tabelle Libri e Documenti (Tabella 3.1).
Libri book1 book2 Documenti cd1 book3 cd2 book1
Se volessimo avere la lista dei documenti che sicuramente non sono dei libri con un assunzione a mondo chiuso la soluzione sarebbe {cd1, book3, cd2} mentre con un’assunzione a mondo aperto la soluzione sarebbe vuota in quanto sappiamo che cd1, book3 e cd2 sono dei documenti ma non sappiamo se sono anche dei libri.
Il mondo aperto è adatto ad applicazioni nelle quali non si possiede conoscenza completa del dominio. Ad esempio per gestire l’informazione università frequentata degli utenti di un social network non si può assume-re che coloro che non l’hanno specificata non ne abbiano fassume-requentato una mentre sappiamo che chi l’ha specificata sicuramente ne ha frequentato una.
Il modo chiuso invece è adatto ai casi in cui si vuole avere l’esatta conoscenza del dominio. Per esempio un’organizzazione deve sapere esattamente chi sono tutti gli impiegati che lavorano per essa.
3.3
Definizione del sistema
Il sistema di tipi si compone di una definizione dei tipi, dell’ambiente e la loro semantica. Successivamente vengono definiti i giudizi su cui si baseranno le regole di tipo ed infine le proprietà del sistema.
3.3.1
Tipi e semantica dei tipi
I tipi che sono stati definiti per il linguaggio SPARQL sono mostrati nella Tabella 3.2. Per ogni tipo ne verrà data una spiegazione e una semantica.
In sistesi un tipo TN (tipo nodo) denota un insieme di nodi che possono essere IriRef, Literal, blank nodes o nulli.
Un tipo TG (tipo grafo) descrive tutte le triple che possono apparire in un grafo secondo un approccio a mondo chiuso ovvero nel grafo possono apparire solo le triple descritte dal tipo.
Un tipo TR (tipo relazione) descrive un insieme di relazioni.
Un tipo NG (tipo ambiente) infine descrive un insieme di ambienti definiti da IriRef associati ad un tipo grafo.
TypeTN ::= T_IRI | T_RDFLiteral | T_BNode | T_NULL | {IriRef} | {lit}
| nameOf(TG)
| TN ∪ TN
| TN ∩ TN
TypeTG ::= TN T_IRI TN | TN IriRef TN |
| TG ∪ TG Type TR ::= [Var : TN] | TR ∪ TR | TR and TR | TR opt TR | []
TypeNG ::= | NG, IriRef : nameOf(TG)
Tabella 3.2: Tipi
Ogni tipo definito denota un insieme di elementi tra loro omogenei. Indicheremo con P(dom) l’insieme di tutti gli insiemi formati da elementi che appartengono a dom ovvero l’insieme di sottoinsiemi di dom (spesso indicato anche con 2dom).
Il tipo nodo TN descrive il tipo che può avere un termine nella posizione di soggetto o oggetto all’interno di una tripla.
Il tipo nodo può essere il tipo T_IRI, il tipo T_RDFLiteral, il tipo T_BNode, il tipo T_NULL introdotto per modellare le variabili senza valore.
Mentre T_RDFLiteral denota l’insieme di tutti i literal, {lit } denota l’insieme che contiene il singolo lit. Mentre T_IRI denota l’insieme di tutti gli IriRef, {IriRef } denota l’insieme con il singolo IriRef.
Un tipo nodo può anche essere il tipo nameOf(TG) ossia il tipo di un IriRef che riferisce un grafo.
Un tipo nodo denota un insieme di GraphTerm. Dato un tipo nodo e un ambiente, la semantica tn rende l’insieme di nodi cui il tipo si riferi-sce. L’unione e intersezione di due tipi nodo comportano rispettivamente l’unione e l’intersezione dei loro insiemi.
GraphTerm= IRIREF ∪ RDFLiteral ∪ BNode ∪ {null} ~_tn: TN → (Env → P{GraphTerm}) ~T_IRItne = IRIREF ~T_RDFLiteraltne = RDFLiteral ~T_BNodetne = BNode ~T_NULLtne = {null} ~{lit}tne = {lit} ~{IriRef}tne = {IriRef}
~nameOf(TG)tne = {IriRef | e(IriRef) ∈ ~TG tg e }
~TN1∪ TN2tne = ~TN1tne ∪ ~TN2tne
~TN1∩ TN2tne = ~TN1tne ∩ ~TN2tne
TG è il tipo di un grafo che denota un insieme di grafi. Il tipo grafo può essere un tipo vuoto oppure contenere triple nella forma {TN1IriRef TN2}
o {TN1 T_IRI TN2}. Nel primo caso il predicato deve essere l’iri IriRef
mentre nel secondo può essere un IriRef qualunque.
Dato un tipo grafo e un ambiente, la semantica tg rende un insieme di grafi. ~_tg: TG → (Env → P{Graph}) ~tge = ∅ ~TN1T_IRI TN2tge = P(G | G ⊆ ~TN1tne × IRIREF × ~TN2tne ) ~TN1IriRef TN2tge = P(G | G ⊆ ~TN1tne × {IriRef} × ~TN2tne ) ~TG1∪ TG2tge = ~TG1tge ∪ ~TG2tge
Il tipo relazione denota un insieme di tabelle. Il tipo relazione più sem-plice è composto da una tabella avente come schema una singola variabile di tipo nodo. La combinazione di tipi relazione comporta delle operazioni relazionali sulle tabelle.
Dato un tipo relazione e un ambiente la semantica tr rende un insieme di relazioni.
~_tr: TR → (Env → P{Rel})
~[Var : TN]tre = P([Var = nodo] | nodo ∈ ~TNtne )
~TR1∪ TR2tre = ~TR1tre ∪+~TR2tre ~TR1 andTR2tr e = ~TR1tre Z ~TR2tre ~TR1 optTR2tr e = ~TR1tre X ~TR2tre ~[]tre = {[]}
Definiamo le operazioni di giunzione, unione e giunzione esterna tra singole relazioni come:
• r1 Z r2come la classica giunzione tra tabelle
• r1 X r2il join esterno definito come: (r1 Z r2)∪(r1×{c1, . . . , cn} → null)
dove {c1, . . . , cn} sono i campi di r2 non presenti in r1
• r1∪+r2come l’unione tra due relazioni con schema diverso ottenuta
aggiungendo colonne di valori nulli nelle tabelle al fine di rendere omogenei gli schemi e quindi eseguire l’unione relazionale
Queste operazioni vengono estese per essere eseguite su insiemi di relazioni. Consideriamo R un insieme di relazioni, le operazioni su questi insiemi vengono definite come:
• R1 Z R2 = {r1 Z r2| r1 ∈ R1, r2 ∈ R2}
• R1 X R2 = {r1 X r2| r1 ∈ R1, r2 ∈ R2}
• R1∪+R2 = {r1∪+r2| r1 ∈ R1, r2 ∈ R2}
Il tipo ambiente NG={IriRef1: TG1, . . . , IriRefn: TGn} denota un insieme
di ambienti in cui ogni IriRefiè legato ad un grafo di tipo TGi.
~_ng : NG → (Env → P{Env}) ~nge = {∅}
~IriRef : nameOf(TG), NGnge = {[IriRef = G | G ∈ ~TG tg
e } × ~NG ng e
IriRef :nameOf (TG ), NG sta ad indicare la concatenazione di un am-biente di grafi NG e un nuovo IriRef che punta ad un grafo di tipo TG.
Con NG,TG indichiamo la concatenazione dell’ambiente NG e il tipo del grafo di default TG. Tale concatenazione descrive l’ambiente in cui viene eseguita la query.
La semantica ngtg rende tutti gli ambienti descritti da tale tipo. ~NG,TGngtge = ~NG ng e × {[Default= G] | G ∈ ~TG tg e }
3.3.2
Judgment
I Judgment sono delle dichiarazioni formali che esprimono delle asser-zioni e hanno la forma
Γ ` =
in cui Γ è un ambiente statico tipizzato e = una asserzione. Le variabili libere indicate in = devono essere dichiarate inΓ. Di seguito sono elencati i judgment per il nostro sistema di tipi.
Tutte le diverse tipologie di query vengono valutate su un tipo ambiente e il loro tipo è: TR per una query select che rende una relazione, TG per una query construct che rende un grafo e Bool per una query ask che rende un booleano.
NG,TG `Sq SelectQuery : TR
NG,TG `CqConstructQuery : TG’
NG,TG `Aq AskQuery : Bool
La DatasetClause agisce sull’ambiente iniziale modificandolo, pertanto avrà come tipo un nuovo tipo ambiente NG’,TG’.
NG,TG `Dc DatasetClause : NG’,TG’
La WhereClause e la GP valutate su un tipo ambiente rendono una relazione, hanno infatti entrambe tipo TR.
NG,TG `Wc WhereClause : TR
NG,TG `Gp GP : TR
SelectClause e ConstructTemplate sono clausole appartenenti rispetti-vamente alle query select e construct. Valutate su un tipo TR hanno rispettivamente tipo TR’ e TG.
TR `Sc SelectClause : TR’
TR `Ct ConstructTemplate : TG
VarOrGTerm valutata su un tipo relazione rende il tipo di un termine della relazione, pertanto ha tipo TN. ValueC invece valutata su un tipo relazione avrà tipo Bool.
TR `Vgt VarOrGTerm : TN
TR `Vc ValueC : Bool
3.3.3
Regole di tipo
Le regole di tipo sostengono la validità di un judgment (conclusione) sulla base di altri judgment chiamati premesse. La forma generale di una regola è
Γ1 ` =1 . . . Γn` =n
Γ ` =
Le premesse stanno al di sopra della linea orizzontale mentre la conclu-sione sta sotto. Quando tutte le premesse sono soddisfatte la concluconclu-sione è verificata.
Il tipo associato ad una SelectQuery, mostrato nella regola TypeSe-lectQuery, è dato dal tipo della SelectClause valutata sul tipo relazione della WhereClause valutata a sua volta sul tipo ambiente NG’,TG’ della DatasetClause.
La TypeSelectClause mostra il tipo della SelectClause composta dalla proiezione di n variabili ognuna con un tipo TN sul tipo relazione in cui
la clausola viene eseguita. Il tipo della SelectClause è quindi dato da tali variabili con i rispettivi tipi.
La TypeSelectClauseAll mostra il tipo della SelectClause senza la proiezione per cui il suo tipo è esattamente il tipo del suo ambiente. (TypeSelectQuery)
NG,TG `DcDatasetClause : NG’,TG’ NG’,TG’ `WcWhereClause : TR
TR `ScSelectClause : TR’
NG,TG `Sq SelectClause DatasetClause WhereClause : TR’
(TypeSelectClause)
TR ` Var1 : TN1, . . . , Varn : TNn
TR `ScselectVar
1, . . . , Varn: [Var1: TN1, . . . , Varn : TNn]
(TypeSelectClauseAll) TR `Scselect’*’ : TR
La TypeConstructQuery è simile alla TypeSelectQuery con la differen-za che la ConstructQuery ha tipo TG in quando rende un grafo.
La TypeConstructTemplate afferma che se ho una Triple che ha tipo TG1su TR e ho un insieme di Triple che ha tipo TG2sullo stesso ambiente,
la sequenza data da Triple . Triple+ ha come tipo l’unione dei due diversi tipi di grafo.
La TypeConstructTemplateBase invece considera una singola tripla del template. Considerati due termini g1 e g2 con il loro tipo che si
tro-vano rispettivamente nella posizione di soggetto e oggetto della tripla; e considerata al posto della proprietà un termine VarOrIri che ha come tipo un insime di IriRef, l’intera tripla avrà come tipo l’unione di tutti i tipi possibili.
(TypeConstructQuery)
NG,TG `Dc DatasetClause : NG’,TG’ NG’,TG’ `WcWhereClause : TR TR `Ct ConstructTemplate : TG’
NG,TG `Cq ConstructTemplate DatasetClause WhereClause : TG’
(TypeConstructTemplate) TR `CtTriple : TG1 TR `Ct Triple+ : TG2 TR `Ct Triple. Triple+ : TG 1∪ TG2 (TypeConstructTemplateBase) TR `Vgt g 1 : TN1 TR `Vgt g2: TN2 TR `VgtVarOrIri : {IriRef 1} ∪. . . ∪ {IriRefn} TR `Ct g
1VarOrIri g2: (TN1IriRef1TN2) ∪. . . ∪ (TN1 IriRefnTN2)
La TypeAskQuery è simile alla TypeSelectQuery e TypeConstructQue-ry, ha tipo Bool.
(TypeAskQuery)
NG,TG `Dc DatasetClause : NG’,TG’
NG’,TG’ `WcWhereClause : TR
NG, TG `Aq askDatasetClause WhereClause : Bool
La TypeFrom e la TypeFromNamed riducono la dimensione della Data-setClause fino al caso terminale della TypeFrom Empty in cui la clausola è vuota.
(TypeFrom)
NG,TG ∪ TG1`Dc DatasetClause : NG’,TG’
NG,TG `Dc DatasetClause from (IriRef : nameOf(TG
1)) : NG’,TG’
(TypeFromNamed)
(NG,IriRef:nameOf(TG1)),TG `Dc DatasetClause : NG’,TG’
NG,TG `Dc DatasetClause from named (IriRef : nameOf(TG
(TypeFromEmpty) NG,TG `Dc : NG,TG
La TypeWhere consiste nella valutazione del graph pattern GP sullo stesso ambiente.
(TypeWhere)
NG,TG `GpGP : TR
NG,TG `Wc whereGP : TR
La regola TypeTriple1 mostra il tipo associato alla variabile Var di una tripla {Var p o} che viene calcolato prendendo l’unione di tutti i tipi TN1 tali che esiste tra le triple di TG una tripla TN1p TN2 in cui TN2 ha
un’intersezione non vuota con il tipo di o. La TypeTriple2 è speculare. (TypeTriple1) S= {TN1 | (TN1p TN2) ∈ TG ∧ (TN ∩∗TN2)} S , ∅ o : TN NG,TG `Tr Var p o : [Var : ∪{TN1∈S}TN1] (TypeTriple2) W= {TN2 | (TN1p TN2) ∈ TG ∧ (TN ∩ ∗ TN1)} W , ∅ s : TN NG,TG `Tr s p Var : [Var : ∪ {TN2∈W}TN2]
Le regole TypeGpAnd, TypeGpOpt e TypeGpUnion mostrano il tipi della combinazione di graph pattern. L’and di due pattern comporta la giun-zione dei tipi, l’opzionalità di un pattern comporta la giungiun-zione esterna e l’unione di pattern comporta l’unione dei tipi.
Nella regola TypeGpFilter la selezione su un graph pattern mantiene il suo tipo.
(TypeGpAnd) NG,TG `Gp GP1 : TR1 NG,TG `GpGP2 : TR2 NG,TG `GpGP 1and GP2 : TR1 and TR2 (TypeGpOpt) NG,TG `Gp GP1 : TR1 NG,TG `GpGP2 : TR2 NG,TG `Gp GP 1optGP2: TR1opt TR2 (TypeGpUnion) NG,TG `Gp GP 1 : TR1 NG,TG `GpGP2 : TR2 NG,TG `Gp GP 1unionGP2 : TR1∪ TR2 (TypeGpFilter) NG,TG `Gp GP : TR TR `Gp VC : Bool NG,TG `GpGP filter VC : TR
Le regole TypeGpGraph e TypeGpIriGraph riguardano l’esecuzione di un graph pattern su un grafo diverso da quello di default. Nella regola TypeGpIriGraph il graph pattern viene eseguito su un unico grafo di tipo TG1 specificato nell’ambiente dei tipi. Invece nella TypeGpGraph i grafi
sono specificati dai valori che la variabile Var assume, il graph pattern viene quindi valutato su ogni grafo appartenente all’ambiente NG.
Se invece i grafi sono più di uno come mostra la regola TypeGpGraph, si valuta il pattern su tutti i grafi dell’ambiente. Il tipo del risultato sarà la giunzione tra i diversi TR e la tabella contenente gli IriRef dei grafi utilizzati.
Con NG[IriRef] selezioniamo un grafo con nome riferito da IriRef : NG[IriRef] = TG se NG = [. . . , IriRef, . . .]
Infine la regola TypeGpEmpty afferma che un graph pattern vuoto non ha un tipo.
(TypeGpIriGraph)
IriRef : nameOf(TG1) ∈ NG NG, TG1`GpGP : TR
NG,TG `GpIriRef graph GP : TR
(TypeGpGraph)
NG, ∪{IriRe f ∈Dom(NG)} NG[IriRef] ` GP : TR
NG,TG `Gp Var graphGP : [Var : Dom(NG)] and TR
(TypeGpEmpty) NG,TG `Gp {} : {}
Il termine ValueC valutato su un tipo relazione avrà sempre tipo Bool. L’unica premessa a questa asserzione è quella di avere un tipo nodo per le variabili a cui si applica il predicato rispetto allo stesso tipo relazione. (TypeVCop)
TR `VgtVar : TN
1 TR `VgtVarOrGTerm : TN2
TR `Vc Var OP VarOrGTerm : Bool (TypeVCisIri) TR `VgtVar : TN TR `VcisIRI(Var) : Bool (TypeVCisLiteral) TR `VgtVar : TN TR `VcisLiteral(Var) : Bool (TypeVCisBlank) TR `VgtVar : TN TR `VcisBlank(Var) : Bool (TypeVClangMatches) TR `VgtVar 1 : TN TR `VgtVar2 : TN TR `VclangMatches(Var 1,Var2) : Bool
(TypeVCbound) TR `VgtVar : TN TR `Vcbound(Var) : Bool (TypeVCsameTerm) TR `VgtVar1 : TN TR `VgtVar2: TN TR `Vc sameTerm(Var 1,Var)2 : Bool (TypeNotVC) TR `VcVC : Bool TR `Vc¬VC : Bool (TypeVCand) TR `VcVC 1 : Bool TR `Vc VC2: Bool TR `VcVC 1∧ VC2: Bool (TypeVCor) TR `VcVC 1 : Bool TR `Vc VC2: Bool TR `VcVC1∨ VC2: Bool
Le regole successive sono molto semplici, ad ogni termine è associato il rispettivo tipo. (VarOrGTermVar) TR `Tr Var : TN TR `VgtVar : TN (TypeVarOrGTermIri) TR `VgtIriRef : {IriRef} (TypeVarOrGTermBnode) TR `Vgtbn : T_BNode
(TypeVarOrGTermLiteral) TR `Vgtlit : T_RDFLiteral[lit]
Le regole TypeAnd mostra in che modo valutare il tipo delle variabili quando l’ambiente è stato dalla congiunzione di due tipi relazione TR1 e
TR2. Considerando una variabile Var definita sia in TR1con tipo TN1che
in TR2 con tipo TN2 l’and fra i due tipi relazione implica che la variabile
abbia un nuovo tipo ottenuto dall’intersezione sui tipi nodo.
Se invece la variabile è definita solo in uno dei due tipi relazione TRi
(con tipo TNi) e non appartiene alle variabili definite nell’altro tipo
rela-zione, essa manterrà il suo tipo TNi. Questo caso è mostrato dalle regole
TypeAnd1 e TypeAnd2. (TypeAnd)
TR1` Var : TN1 TR2` Var : TN2
TR1and TR2 ` Var : TN1∩ TN2
(TypeAnd1)
TR1` Var : TN1 Var < VarSet(TN2)
TR1and TR2 ` Var : TN1
(TypeAnd2)
TR2` Var : TN2 Var < VarSet(TN1)
TR1and TR2 ` Var : TN2
Le regole TypeOpt mostrano un tipo relazione seguito da un altro tipo relazione opzionale. Consideriamo sempre la nostra variabile Var. Se essa è definita in entrambi i tipi relazione, avrà come tipo TN1. Se la variabile
è definita solo nel tipo relazione del graph pattern, ossia TR1, manterrà il
suo tipo TN1 come mostra la regola TypeOpt1. Se invece una variabile è
definita solo nel pattern opzionale, ossia TR2, allora può avere il suo tipo
(TypeOpt)
TR1` Var : TN1 TR2` Var : TN2
TR1 opt TR2 ` Var : TN1
(TypeOpt1)
TR1` Var : TN1 Var < VarSet(TR2)
TR1opt TR2` Var : TN1
(TypeOpt2)
TR2` Var : TN2 Var < VarSet(TR1)
TR1opt TR2 ` Var : TN2∪ T_NULL
Quando l’ambiente è dato dall’unione di due tipi relazione come mostra la regola TypeUnion, il tipo della variabile Var consiste nell’unione dei tipi TN se questa è definita in entrambi i tipi relazione. Se questa è definita solo in un tipo relazione allora avrà come tipo l’unione del suo tipo nodo con il tipo nullo.
(TypeUnion)
TR1` Var : TN1 TR2` Var : TN2
TR1∪ TR2` Var : TN1∪ TN2
(TypeUnion1)
TR1` Var : TN1 Var < VarSet(TR2)
TR1∪ TR2 ` Var : TN1∪ T_NULL
(TypeUnion2)
TR2` Var : TN2 Var < VarSet(TR1)
TR1∪ TR2 ` Var : TN2∪ T_NULL
3.3.4
Proprietà
Un sistema di tipi permette di dimostrare determinate proprietà delle espressioni del linguaggio corrispondente. Per il sistema di tipi
propo-sto viene studiata la proprietà di soundness (teorema 1) che possiamo esprimere nei seguenti termini generali:
Teorema 1 (Upper Bound). Per ogni tipo ambiente Γ, per ogni
ambiente e ∈ ~Γ, per ogni query Q:
Γ ` Q : T ⇒ ~Qe∈ ~Te
Di seguito viene riportata, sottoforma di congettura in quanto non ne daremo la dimostrazione, l’applicazione della proprietà esposta ad ogni judgment del sistema di tipi definito.
NG,TG `Sq SelectQuery : TR ⇒ ∀e ∀e1 ∈ ~NG,TGngtg e . ~SelectQuery Sq e1 ∈ ~TR tr e1 TR `Sq SelectClause : TR 1 ⇒ ∀e ∀r ∈ ~TRtr e . ~SelectClauseScr ∈ ~TR1tre NG,TG `CqConstructQuery : TG ⇒ ∀e ∀e1 ∈ ~NG,TGngtg e . ~ConstructQuery Cq e1 ∈ ~TG tg e1 TR `Ct ConstructTemplate : TG ⇒ ∀e ∀t ∈ ~TRtr e . ~ConstructTemplateCtt ∈ ~TG tg e TR `VgtVarOrGTerm : TN ⇒ ∀e ∀t ∈ ~TRtr e . ~VarOrGTerm Vgt t ∈ ~TNtne NG,TG `Aq AskQuery : Bool ⇒ ∀e ∀e1 ∈ ~NG,TGngtg e . ~AskQuery Aq e1 ∈ ~Boole NG,TG `Dc DatasetClause : NG’,TG’ ⇒ ∀e ∀e1 ∈ ~NG,TGngtg e . ~DatasetClauseDce1 ∈ ~NG’,TG’ ngtg e1 NG,TG `WcWhereClause : TR ⇒ ∀e ∀e1 ∈ ~NG,TGngtg e . ~WhereClauseWce1 ∈ ~TRtre1
NG,TG `GpGP : TR ⇒ ∀e ∀e1 ∈ ~NG,TGngtg e . ~GP Gp e1 ∈ ~TR tr e1 TR `Vc ValueC : Bool ⇒ ∀e ∀t ∈ ~TRtr e . ~ValueCVct ∈ ~Boole
Per esempio consideriamo la prima proprietà NG,TG `Sq SelectQuery : TR ⇒ ∀e ∀e1 ∈ ~NG,TGngtg e . ~SelectQuery Sq e1 ∈ ~TR tr e1
Questa stabilisce che per ogni ambiente e la valutazione di NG,TG su tale ambiente rende un altro ambiente e1 ; la valutazione su tale ambiente della SelectQuery, renderà come tipo un sottoinsieme del tipo TR valutato sempre su e1.