Base delle definizioni

2

Supponiamo di avere un insieme di funzioni che caratterizzano qualcosa: nei metodi del mondo OO che caratterizzano un tipo. In matematica queste sono proposizioni e abbiamo due tipi: assiomi e lemmi. Gli assiomi sono assunzioni, i lemmi sono facilmente derivati da loro. Negli assiomi C ++ sono pure funzioni virtuali.

Ecco il problema: c'è più di un modo per assiomatizzare un sistema. Dato un insieme di proposizioni o metodi, un sottoinsieme delle proposizioni che è necessario e sufficiente per derivare tutti gli altri è chiamato una base.

Allo stesso modo, per i metodi o le funzioni, abbiamo un insieme desiderato che deve essere definito, e in genere ognuno ha una o più definizioni in termini degli altri, e chiediamo al programmatore di fornire definizioni di istanza che siano sufficienti per consentire tutti gli altri da definire e, se c'è un eccesso di specificazione, allora è coerente.

Lasciatemi fare un esempio (in Felix, il codice Haskell sarebbe simile):

class Eq[t] {
  virtual fun ==(x:t,y:t):bool => eq(x,y);
  virtual fun eq(x:t, y:t)=> x == y;
  virtual fun != (x:t,y:t):bool => not (x == y);
  axiom reflex(x:t): x == x;
  axiom sym(x:t, y:t): (x == y) == (y == x);
  axiom trans(x:t, y:t, z:t): implies(x == y and y == z, x == z);
}

Qui è chiaro: il programmatore deve definire == o eq o entrambi. Se entrambi sono definiti, le definizioni devono essere equivalenti. La mancata definizione di uno non causa un errore del compilatore, causa un loop infinito in fase di esecuzione. Definire entrambi inequivocabilmente non causa nemmeno un errore, è solo incoerente. Si noti che gli assiomi specificati vincolano la semantica di qualsiasi definizione. Data una definizione di == direttamente o tramite una definizione di eq, allora! = Viene definito automaticamente, anche se il programmatore potrebbe sostituire l'impostazione predefinita con qualcosa di più efficiente, chiaramente tale overspecification deve essere coerente.

Si noti che == potrebbe anche essere definito in termini di! =, ma non lo abbiamo fatto.

Una caratterizzazione di un ordine parziale o totale è più complessa. È molto più impegnativo in quanto vi è un'esplosione combinatoria di basi possibili.

C'è una ragione per desiderare una eccessiva precisazione: le prestazioni. C'è anche un altro motivo: scelta e convenienza.

Quindi qui ci sono diverse domande: una è come controllare che la semantica sia rispettata e non sto cercando una risposta qui (troppo difficile!). L'altra domanda è:

Come possiamo specificare e verificare che un'istanza fornisca almeno una base?

E una domanda molto più difficile: come possiamo fornire diverse definizioni predefinite che dipendono dalla base scelta?

    
posta Yttrill 07.01.2012 - 02:24
fonte

3 risposte

3

In C++ axioms are pure virtual functions.

Non proprio. Le funzioni virtuali pure riguardano solo il polimorfismo di runtime, ciò non ha nulla a che fare con gli assiomi.

Ciò che puoi fare (che è comunemente fatto) è definire nuovi operatori attraverso il CRTP che sono definiti in termini di alcuni sottoinsiemi di quelli esistenti - comunemente fatti con operatori relazionali e aritmetici. Tuttavia, C ++ attualmente non contiene alcun meccanismo standard per gli assiomi. È stato considerato ma respinto insieme a Concepts, afaik. E come qualcosa che non puoi nemmeno descrivere , è sicuramente impossibile verificare, nel caso generale, che ciò implicherebbe la soluzione del problema di interruzione.

    
risposta data 05.06.2012 - 09:28
fonte
0

In generale, le dipendenze tra proposizioni formano un digrafo, che può, come tu fai notare, contenere cicli. Un sottoinsieme completo minimo è definito da un insieme di nodi tale che tutti gli altri nodi sono raggiungibili da (almeno) un nodo nel set. Non credo che ci sia un linguaggio che ti permetta di specificarlo direttamente; in Haskell la soluzione tipica è quella di documentare sottoinsiemi convenienti e mantenere le classi di caratteri piccole e semplici. Prendi Eq ad esempio:

class Eq a where
  (==), (/=) :: a -> a -> Bool
  x == y = not (x /= y)
  x /= y = not (x == y)

In questo caso, le definizioni minime complete includono (==) e (/=) , il che è abbastanza ovvio che non ha realmente bisogno di essere verificato. Direi che un typeclass con una complessità tale da dare una pausa al programmatore è troppo complesso, e garantisce il refactoring.

Se vuoi solo specificare alcuni set minimi ragionevoli, puoi lasciare l'abstract della definizione principale e ricavare una classe di caratteri per ciascuno. Ma questo diventa rapidamente ingombrante, e in Haskell ancora non veramente sapere che l'utente ha implementato correttamente la tua interfaccia.

Ma non è responsabilità dell'utente , come autore dell'interfaccia, definire il comportamento per l'uso improprio dell'interfaccia.

    
risposta data 07.01.2012 - 06:56
fonte
0

Rischia di uscire dai binari in almeno due modi:

  1. Le funzioni pure virtuali di C ++ non sono come gli assiomi. Un assioma è un'ipotesi definita. Una pura funzione virtuale è l'assenza o l'aspettativa di una definizione. È necessario un set di assiomi per creare un sistema matematico; una classe C ++ non ha bisogno di contenere una singola funzione virtuale, pura o altrimenti.

  2. Stai utilizzando due distinte nozioni di derivazione . I lemmi sono derivati attraverso l'applicazione di assiomi. Non puoi affermare che un'espressione è un lemma a meno che non puoi dimostrare che è il risultato di assiomi e nient'altro. L'insieme di assiomi determina completamente l'insieme di possibili lemmi. Nella terminologia OOP, una classe o un metodo può essere derivato da un altro, ma è una relazione diversa da quella dei lemmi agli assiomi in quanto il creatore della classe o del metodo è libero di aggiungere o rimuovere parti.

So here, there are several questions: one is how to check semantics are obeyed and I am not looking for an answer here (way too hard!).

C'è una grande quantità di ricerche sul tema della dimostrazione della correttezza dei programmi. Potresti essere interessato a leggere la verifica formale . Altri due argomenti che potrebbero interessarti sono sistemi di inferenza e grammatiche formali .

How can we specify, and check, that an instance provides at least a basis?

Stai parlando specificamente del codice o di qualsiasi "insieme di funzioni che caratterizzano qualcosa"? E cosa intendi con "istanza"? Nonostante queste preoccupazioni e quelle precedenti, un approccio è:

  • Enumera tutte le definizioni nel sistema.

  • Per ogni definizione d , decidi se d dipende esclusivamente da altre definizioni nel sistema e nient'altro. In tal caso, rimuovi d dal sistema.

  • Qualunque cosa rimanga nel sistema è per definizione la "base", ovvero l'insieme di definizioni necessarie per creare il sistema originale.

risposta data 05.06.2012 - 11:47
fonte

Leggi altre domande sui tag