-calcolo con riflessione


23

Sto cercando un semplice calcolo che supporti il ​​ragionamento sulla riflessione , ovvero l'introspezione e la manipolazione dei programmi in esecuzione.

Esiste un'estensione -calculus non tipizzata che consente di convertire -terms in una forma che può essere sintatticamente manipolata e successivamente valutata?λλ

Immagino che il calcolo abbia due principali termini aggiuntivi:

  • v vreflect v : prende e produce una rappresentazione di modificabile alla manipolazione sintattica.vv
  • eval v : prende una rappresentazione sintattica di un termine e lo valuta.

Per supportare la riflessione, è richiesta una rappresentazione sintattica dei termini. Sarebbe simile a:

  • ( L A M R ( e ) ) R ( e ) eλx.e verrebbe rappresentato come un termine , dove è la versione riflessa di ,(LAM R(e))R(e)e
  • ( A P P R ( e ) R ( e ) )e e sarebbe rappresentato come termine , e(APP R(e) R(e))
  • ( V A R x )x verrebbe rappresentato come .(VAR x)

Con questa rappresentazione, la corrispondenza dei modelli potrebbe essere utilizzata per manipolare i termini.

Ma abbiamo un problema. e devono essere codificati come termini, così come la corrispondenza dei pattern. Affrontare questo sembra essere semplice, aggiungendo , e , ma dovrò aggiungere altri termini per supportare la manipolazione di questi?reflectevalREFLECTEVALMATCH

Ci sono scelte progettuali che devono essere fatte. Cosa dovrebbe fare la funzione sopra menzionata con il corpo di e ? dovrebbe trasformare il corpo o no?R()reflectevalR()

Dato che non sono molto interessato allo studio della riflessione stessa - il calcolo servirebbe da veicolo per altre ricerche - non voglio reinventare la ruota.

Esistono calcoli esistenti che corrispondono a ciò che ho appena descritto?

Per quanto ne so, calcoli come MetaML, suggeriti in un commento, fanno molta strada, ma non includono la possibilità di modellare la corrispondenza e decostruire frammenti di codice che sono già stati creati.

Una cosa che vorrei poter fare è la seguente:

  • let x=λy.y in reflect x(LAM (VAR y) (VAR y))

Quindi esegui la corrispondenza del modello sul risultato per creare un'espressione completamente diversa.

Questa non è certamente un'estensione conservativa al -calculus e la meta-teoria sarà probabilmente brutta, ma questo è un po 'il punto per la mia applicazione. Voglio spezzare -struzioni a parte.λλλ


MetaML è un linguaggio riflettente tipizzato con l'operatore di bracketing che esegue il tuo REFLECT e non bracketing di EVAL. La digitazione è di base, ma puoi vedere il frammento ereditato da S4 modale in questo lavoro che può aiutarti.
ex0du5,

@ ex0du5: Grazie, ma questo non va abbastanza lontano, per quanto posso dire. Certo, posso costruire codice in varie fasi, ma non riesco a separare i termini. (Leggerò più da vicino, per vedere se mi sono perso qualcosa.)
Dave Clarke,

Schema (senza mutabilità e altre complicazioni)?
Gilles 'SO- smetti di essere cattivo' il

@Gilles: lo schema è un linguaggio di programmazione, non un calcolo. Inoltre, non penso che possa fare quello che voglio.
Dave Clarke,

@DaveClarke Un linguaggio di programmazione è un calcolo con molte verruche. Un core Scheme sembra adatto a prima vista, ma non ho dato abbastanza idee ai tuoi requisiti per esserne sicuro. Cosa pensi che non funzionerebbe? (Entra per chattare se vuoi.)
Gilles 'SO- smetti di essere malvagio' il

Risposte:


15

Jean Louis Krivine ha introdotto un calcolo astratto che estende la "Macchina Krivine" in un modo molto banale (si noti che la macchina Krivine supporta già l'istruzione call / cc di lisp):

Egli introduce un operatore di "quote" in questo articolo definite nel modo seguente: se è un λ -termine, nota n Phi; l'immagine di φ da alcuni biiezione π : À N di condizioni lambda ai numeri naturali. Nota ¯ n il numero chiesa che corrisponde al n N . Krivine definisce l'operatore χ secondo la regola di valutazione: χ ϕ ϕ ¯ n ϕϕλnϕϕπ:ΛNn¯nNχ

χ ϕϕ nϕ¯
Credo che la magia di Kleene mostrerà che questo è sufficiente per fare ciò che desideri: cioè definire un operatore di preventivo e valutazione, se è calcolabile.π

Nota che Krivine è notoriamente difficile da leggere (per favore non arrabbiarti se leggi questo, Jean-Louis!), E alcuni ricercatori hanno fatto l'atto di beneficenza nel tentativo di estrarre il contenuto tecnico in un modo più leggibile. Potresti provare a dare un'occhiata a queste note di Christophe Raffali.

Spero che sia di aiuto!


Mi viene in mente che esiste un altro riferimento che può essere rilevante per i tuoi interessi: il Pure Pattern Calculus di Jay e Kesner formalizza una variante del calcolo che estende l'astrazione semplice su una variabile a un'astrazione su uno schema che rappresenta un calcolo di schema si. Questo è straordinariamente espressivo e in particolare consente di decostruire un'applicazione stessa: se non sbaglio, il termine:λ

(λ(x y).x)((λx.x x) (λy.y))

riduce a . Ancora una volta, credo che questo sia più che sufficiente per implementare gli operatori di preventivo e valutazione .λx.x x


Vorrei dare il mio voto a questa risposta apparentemente ragionevole, ma non ho idea se inizi a rispondere alla domanda.
Raffaello

@Raphael leggi gli articoli e scoprilo :) In verità, questa è solo una risposta parziale: gli articoli in effetti formalizzano un'importante caratteristica di lisp che non si trova nel calcolo lambda: vale a dire l'operatore QUOTE. Non esiste un ampio studio meta-teorico, ma lo introducono solo come mezzo per esprimere una sorta di strano calcolo non trasparente al fine di realizzare complicati assiomi della teoria degli insiemi.
cody

1
Se ricordo bene, in PPC, non puoi modellare la corrispondenza sui redex, il motivo che hanno dato è per motivi di confluenza. Inoltre, in PPC, la corrispondenza del modello è rigorosa sull'abbinamento, quindi verrà immediatamente normalizzato a λ y . y , quindi il tentativo di abbinarlo al modello ( x y ) fallirà. (λx.x x) (λy.y)λy.y(x y)
giorno

1
L'unica citazione che conosco è quella di Lisp. Ma, come ricordo, cambia semplicemente tutto ciò che viene citato in un oggetto sintattico. La "funzione" prende il suo argomento non valutata .. la r e f l e c t funzione deve prendere il valore del suo argomento (valutare) e riattivarlo in qualche espressione sintattica che valuta (come ?) a quel valore. Quindi, se le offerte formalismo Krivine con il LISP q u o t e , siamo da nessuna parte vicino a quello che è suggerito nella domanda. quotereflectquote
babou,

8

Farlo è molto difficile, se non impossibile, senza rinunciare alla confluenza. Vale a dire, sospetto che tu abbia ragione su una meta-teoria pelosa. D'altra parte, è possibile progettare un calcolo combinatore in grado di esprimere tutte le funzioni calcolabili turing e che ha la piena capacità di ispezionarne i termini: vedere Jay e Give-Wilson .

Credo che avere questa capacità faccia cose cattive per la tua teoria equazionale. In particolare tenderai a dimostrare che due valori sono uguali solo se equivalgono a equivalenti alfa.

Non ho ancora letto il codice di Krivine collegato, ma dovrei notare che nella logica classica hai essenzialmente solo due cose: vero e falso. Tutto è equivalente a uno di quelli. Cioè, tendi ad avere comunque una teoria equazionale collassata.


1
Si noti che il calcolo di Krivine non è un calcolo di proposizioni ma piuttosto di realizzatori per queste, che hanno una teoria equazionale altamente non banale.
codice

5

Nella teoria dei linguaggi di programmazione la caratteristica di cui parli viene generalmente definita "citazione". Ad esempio, John Longley ne ha scritto in alcuni dei suoi lavori, vedi questo documento .

Se stai solo seguendo considerazioni teoriche (al contrario di un'implementazione davvero utile) allora puoi semplificare le cose affermando che quote(o reflectcome lo chiami) si mappa nel tipo di numeri interi natrestituendo un codice Gödel del suo argomento. È quindi possibile scomporre il numero proprio come si farebbe con un albero di sintassi astratto. Inoltre, non è necessario evalperché può essere implementato nella lingua: è essenzialmente un interprete per la lingua.

nmφn(m)φnnλquote

Se mi dici cosa stai cercando, potrei essere in grado di darti riferimenti più specifici.

A proposito, ecco un problema aperto:

λquoteξ

ξ

e1e2λx.e1λx.e2
λλquotequote
e1e2quotee1quotee2,
quote((λx.x)y)quotey.
quoteλ

βquoteλξ

ξβ

Il seguente documento mostra alcuni problemi con l'equazione (ξ): Il calcolo Lambda è algebrico, Peter Selinger. Interessante, qualcosa di nuovo che non ero a conoscenza! Freddo.
Numeri transfiniti

4

Ecco una risposta alternativa, invece di usare il mio approccio nominale, che è ancora sperimentale, c'è un approccio più consolidato che risale al documento:

LEAP: una lingua con eval e polimorfismo
Frank Pfenning e Peter Lee
https://www.cs.cmu.edu/~fp/papers/tapsoft89.pdf

Il documento inizia con:

Questo ci ha portato quindi alla domanda, prima posta da Reynolds, se le lingue fortemente tipizzate ammettano interpreti metacircolari. La saggezza convenzionale sembrava indicare che la risposta era "No". La nostra risposta è "Quasi".

Si noti che LEAP è molto più forte di ciò che l'OP vuole. Prima di tutto viene digitato. E in secondo luogo chiede metacircolarità, il che significa ad esempio che eval può eseguire la propria definizione. In Prolog ottieni metacircolarità per risolvere / 1:

solve(true).
solve((A,B)) :- solve(A), solve(B).
solve(H) :- clause(H,B), solve(B).

Se aggiungi la seguente clausola per risolvere / 1:

solve(clause(H,B)) :- clause(H,B).

E se vedi che quella clausola / 2 restituisce anche le clausole di solving / 1. È quindi possibile chiamare risolvere (risolvere (...)) e vedere come si risolve risolve.

Domande di autorappresentazione stimolano ancora qualche ricerca, vedi ad esempio:

Autorappresentazione nel sistema Girards U
Matt Brown, Jens Palsberg
http://compilers.cs.ucla.edu/popl15/popl15-full.pdf


3

Il problema è identificato nella fedeltà degli assistenti di prova come Coq e Isabelle / HOL. Va sotto l'acronimo HOAS . Ci sono alcune affermazioni su λ-Prolog secondo cui attraverso il nuovo quantificatore such si possono fare cose del genere. Ma non ho ancora avuto un'idea di questa affermazione. Immagino che l'intuizione principale che ho ottenuto finora sia che non esiste un approccio definito, ci sono un paio di possibili approcci.

La mia interpretazione , non ancora terminata , è ispirata a un recente articolo di Paulson sulla dimostrazione dell'incompletezza di Gödels. Vorrei usare i raccoglitori a livello di oggetto in relazione ad una struttura di dati che ha i nomi a livello meta. Fondamentalmente una struttura di dati simile ma distinta come quella dell'OP, e con la codifica della Chiesa poiché sono interessato a tipi dipendenti:

datatype Expr = var Name                 /* written as n */
              | app Expr Expr            /* written as s t */
              | abs Name Expr Expr       /* written as λn:s.t */

Le espressioni a livello meta possono essere distinte dalle espressioni a livello di oggetto in quanto utilizziamo i nomi delle variabili n, m, ecc. Per indicare i nomi. Considerando che usiamo i nomi delle variabili x, y, .. ecc. A livello di oggetto. L'interpretazione di un meta termine nella logica dell'oggetto funzionerebbe quindi come segue. Scriviamo [t] σ per l'interpretazione del termine nominale t nel contesto nominale σ, che dovrebbe dare un termine oggetto. Avremmo quindi:

 [n]σ = lookup σ n
 [s t]σ = [s]σ [t]σ
 [λn:s.t]σ = λx:[s]σ.[t]σ,n:x

Quanto sopra definirebbe ciò che l'OP chiama una funzione EVAL. Piccola differenza rispetto a Paulson, σ è solo un elenco finito e non funzionale. Secondo me sarebbe possibile introdurre solo una funzione EVAL e non una funzione REFLECT. Dal momento che a livello di oggetto potresti avere una certa uguaglianza in modo che le diverse espressioni lambda siano le stesse. Quello che devi fare sarebbe usare eval per ragionare possibilmente anche sulla riflessione se ne senti il ​​bisogno.

Dovresti andare agli estremi come Prolog dove nulla è espanso, se vuoi abbattere il muro tra nominale e non nominale. Ma come mostra l'esempio del sistema λ-Prolog, nel caso di ordine superiore si stanno attirando ulteriori problemi che possono ad esempio essere superati solo in modo logico introducendo nuovi mezzi come un quantificatore!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.