Coppia di basi combinatrice completa più semplice per espressioni piatte


9

Nell'articolo di Chris Okasaki " Flattening Combinators: Surviving Without Parentheses " mostra che due combinatori sono entrambi sufficienti e necessari come base per codificare espressioni complete di Turing senza la necessità di un operatore dell'applicazione o di parentesi.

Rispetto alle codifiche di John Trump della logica combinatoria in " Calcolo lambda binario e logica combinatoria " attraverso la codifica di prefissi combinatori S e K con un operatore dell'applicazione, solo la necessità di due combinatori per le espressioni piatte aumenta la densità del codice all'ottimalità. La numerazione di Goedel risultante associa ogni intero a un'espressione a termine chiuso valida e ben formata a differenza della maggior parte dei calcoli e degli esolang rilevanti relativi alla lunghezza minima delle descrizioni le cui rappresentazioni canoniche di solito consentono la descrizione di programmi sintatticamente non validi.

Tuttavia, la codifica di Okasaki doveva essere molto utile in una mappatura unidirezionale dai termini del calcolo lambda ai bittring, non necessariamente viceversa, poiché i due combinatori utilizzati in questa riduzione sono relativamente complessi se usati come istruzioni pratiche di sostituzione.

Qual è la coppia base combinatrice completa più semplice che non richiede un operatore dell'applicazione?


1
Non sono sicuro se pertinente, ma: nota che ci sono basi del calcolo lambda formate da un singolo termine. Ciò rende la numerazione di Gödel ancora più semplice. cs.uu.nl/research/techreps/repo/CS-1989/1989-14.pdf
chi

Risposte:


2

Tornando a questo quasi un anno dopo, mi sono reso conto di aver perso alcune ricerche critiche prima di pubblicare.

Jot sembra adattarsi al conto di quello che stavo chiedendo, con due combinatori relativamente semplici B e X che possono essere rappresentati da una numerazione Goedel compatta.

Ho semplificato la sua implementazione di riferimento con Python:

def S(x): return lambda y: lambda z: x(z)(y(z))
def K(x): return lambda y: x
def X(x): return x(S)(K)
def B(x): return lambda y: lambda z: x(y(z))
def I(x): return x
def J(n): return (B if n & 1 else X)(J(n >> 1)) if n else I

J (n) restituisce la funzione costruita che indica il programma rappresentato dal suo numero Goedel n.

B (equivalente alla moltiplicazione codificata da Church) svolge la funzione di applicazione funzionale (parentesi) e può isolare le metà S / K del combinatore Iota a base singola X.

Ci sono alcune proprietà importanti di questo linguaggio che sto quasi quasi spudoratamente rubando dal sito web dell'inventore del linguaggio Chris Barker, circa 2000.

Jot è un linguaggio regolare in sintassi ma completo di Turing. Dall'implementazione di J (n) si può vedere che se una lingua host supporta la ricorsione della coda, non è necessario spazio nello stack per analizzare il formato del programma di bitstring.

La prova della completezza di Turing proviene anche dal sito di Chris, implementando la già nota logica combinatoria completa di Turing usando i combinatori S e K:

K  ==> 11100
S  ==> 11111000
AB ==> 1[A][B], where A & B are arbitrary CL combinators built up from K & S

Jot non ha errori di sintassi, ogni programma dato il suo numero Goedel n è un programma valido. Questo è probabilmente l'aspetto più importante della mia ricerca, poiché non solo semplifica l'analisi della banalità, ma in teoria dovrebbe anche rendere Jot molto più parsimonioso di qualsiasi codifica completa di Turing che debba saltare programmi malformati.

Ho scritto alcuni strumenti per "risolvere" con la forza bruta il problema semi-indecifrabile di trovare la complessità di Kolmogorov di una funzione in Jot. Funziona facendo affidamento sul programmatore per specificare alcuni esempi di allenamento molto caratteristici della mappatura di una funzione, quindi enumera tutti i programmi Jot fino a quando tutti gli esempi di allenamento sono abbinati e infine tenta una prova dell'uguaglianza di una funzione trovata con l'implementazione verbosa originale.

Attualmente funziona solo fino a ~ 40 bit con le mie risorse limitate. Sto tentando una riscrittura con un solutore SAT per apprendere programmi molto più grandi. Se sai come srotolare le chiusure annidate limitate come formula booleana, ti preghiamo di aiutarti con la mia nuova domanda .

Ora per alcuni interessanti confronti con Binary Lambda Calculus di John Tromp, che è noto per la sua concisione, ma presenta il problema di possibili errori di sintassi. I seguenti programmi sono stati generati dal mio programma di apprendimento in pochi secondi.

Function    Jot       Binary Lambda Calculus   |J| |B|
--------|----------|--------------------------|---|---
SUCC      J(18400)  "000000011100101111011010" 15  24
CHURCH_0  J(154)    "000010"                    8   6
CHURCH_1  J(0)      "00000111010"               1  11
CHURCH_2  J(588826) "0000011100111010"         20  16
IS_ZERO   J(5)      "00010110000000100000110"   3  23
MUL       J(280)    "0000000111100111010"       9  19
EXP       J(18108)  "00000110110"              15  11
S         J(8)      "00000001011110100111010"   4  23
K         J(4)      "0000110"                   3   7
AND       J(16)     "0000010111010000010"       5  19
OR        J(9050)   "00000101110000011010"     14  20

Dai miei esperimenti, l'ipotesi che Jot porti a programmi più piccoli viene lentamente confermata mentre il mio programma apprende funzioni semplici, le compone, quindi apprende funzioni più grandi da un soffitto migliorato.

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.