SQL hatta TSQL Turing Tamamlandı mı?


171

Bu bugün ofise geldi. Böyle bir şey yapma planım yok, ama teorik olarak SQL'de bir derleyici yazabilir misiniz? İlk bakışta, birçok problem sınıfı için son derece külfetli olsa da, tam turing gibi görünüyor.

Turing tamamlanmazsa, bunun için ne gerekir?

Not: SQL'de bir derleyici yazmak gibi bir şey yapmak istemiyorum, bunun aptalca bir şey olacağını biliyorum, bu yüzden bu tartışmayı önleyebilirsek takdir ediyorum.

Yanıtlar:


219

PL / SQL veya PSM gibi gerçek bir 'komut dosyası' uzantısı olmadan bile SQL'in Turing Complete olabileceği ortaya çıkıyor (gerçek programlama dilleri olarak tasarlanmış, bu da biraz hile yapıyor).

Bu slayt setinde Andrew Gierth, CTE ve Windowing SQL ile Turing Complete olduğunu kanıtlayan bir döngüsel etiket sistemi oluşturarak Turing Complete olduğunu kanıtlıyor. Bununla birlikte, CTE özelliği önemli bir parçasıdır - kendilerine başvurabilecek adlandırılmış alt ifadeler oluşturmanıza ve böylece sorunları tekrar tekrar çözmenize olanak tanır.

İlginç olan nokta, CTE'nin SQL'i bir programlama diline dönüştürmek için gerçekten eklenmediğidir - sadece bir bildirim sorgulama dilini daha güçlü bir bildirim sorgulama diline dönüştürmek. Meta programlama dili oluşturmak için tasarlanmamış olsalar bile, şablonlar Turing olarak tamamlandı.

Oh, SQL örneğinde ayarlanan Mandelbrot da çok etkileyici :)


1
Oracle SQL de oldukça hasta bir şekilde olsa da tamamlanıyor: blog.schauderhaft.de/2009/06/18/…
Jens Schauder

2
> SQL ortaya çıkıyor Bunu söylememeli: SQL: 1999 çıkıyor? Sadece bunu söylemek, çünkü CTE'ler 99 sürümünde eklendi ve çok fazla insan standart sql'i Sql 92 ile ilişkilendirdi.
Ernesto

1
@JensSchauder, "Oracle $ teknolojisi, oldukça hasta bir şekilde olmasına rağmen $ some_good_feature" şeklinde genelleştirilebilir
Rob Grant

3
9 yıl oldu ama bu ilginç olabilir beta.observablehq.com/@pallada-92/sql-3d-engine
Loupax

33

Belirli bir programlama dilinin, bir Turing makinesine hesaplamaya eşdeğer olduğu gösterilebiliyorsa, Turing-complete olarak söylenir.

TSQL'de bir BrainFuck tercümanı yapabileceğimiz için TSQL Tamamlanıyor .

SQL'de BrainFuck yorumlayıcısı - GitHub

Sağlanan kod bellekte çalışır ve veritabanını değiştirmez.

-- Brain Fuck interpreter in SQL

DECLARE @Code  VARCHAR(MAX) = ', [>,] < [.<]'
DECLARE @Input VARCHAR(MAX) = '!dlroW olleH';

-- Creates a "BrainFuck" DataBase.
-- CREATE DATABASE BrainFuck;

-- Creates the Source code table
DECLARE @CodeTable TABLE (
    [Id]      INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Command] CHAR(1) NOT NULL
);

-- Populate the source code into CodeTable
DECLARE @CodeLen INT = LEN(@Code);
DECLARE @CodePos INT = 0;
DECLARE @CodeChar CHAR(1);

WHILE @CodePos < @CodeLen
BEGIN
    SET @CodePos  = @CodePos + 1;
    SET @CodeChar = SUBSTRING(@Code, @CodePos, 1);
    IF @CodeChar IN ('+', '-', '>', '<', ',', '.', '[', ']')
        INSERT INTO @CodeTable ([Command]) VALUES (@CodeChar)
END

-- Creates the Input table
DECLARE @InputTable TABLE (
    [Id]   INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Char] CHAR(1) NOT NULL
);

-- Populate the input text into InputTable
DECLARE @InputLen INT = LEN(@Input);
DECLARE @InputPos INT = 0;

WHILE @InputPos < @InputLen
BEGIN
    SET @InputPos = @InputPos + 1;
    INSERT INTO @InputTable ([Char])
    VALUES (SUBSTRING(@Input, @InputPos, 1))
END

-- Creates the Output table
DECLARE @OutputTable TABLE (
    [Id]   INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Char] CHAR(1) NOT NULL
);

-- Creates the Buffer table
DECLARE @BufferTable TABLE (
    [Id]     INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Memory] INT DEFAULT 0  NOT NULL
);
INSERT INTO @BufferTable ([Memory])
VALUES (0);

-- Initialization of temporary variables 
DECLARE @CodeLength INT = (SELECT COUNT(*) FROM @CodeTable);
DECLARE @CodeIndex  INT = 0;
DECLARE @Pointer    INT = 1;
DECLARE @InputIndex INT = 0;
DECLARE @Command    CHAR(1);
DECLARE @Depth      INT;

-- Main calculation cycle
WHILE @CodeIndex < @CodeLength
BEGIN
    -- Read the next command.
    SET @CodeIndex = @CodeIndex + 1;
    SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex);

    -- Increment the pointer.
    IF @Command = '>'
    BEGIN
        SET @Pointer = @Pointer + 1;
        IF (SELECT [Id] FROM @BufferTable WHERE [Id] = @Pointer) IS NULL
            INSERT INTO @BufferTable ([Memory]) VALUES (0);
    END

    -- Decrement the pointer.
    ELSE IF @Command = '<'
        SET @Pointer = @Pointer - 1;

    -- Increment the byte at the pointer.
    ELSE IF @Command = '+'
        UPDATE @BufferTable SET [Memory] = [Memory] + 1 WHERE [Id] = @Pointer;

    -- Decrement the byte at the pointer.
    ELSE IF @Command = '-'
        UPDATE @BufferTable SET [Memory] = [Memory] - 1 WHERE [Id] = @Pointer;

    -- Output the byte at the pointer.
    ELSE IF @Command = '.'
        INSERT INTO @OutputTable ([Char]) (SELECT CHAR([Memory]) FROM @BufferTable WHERE [Id] = @Pointer);

    -- Input a byte and store it in the byte at the pointer.
    ELSE IF @Command = ','
    BEGIN
        SET @InputIndex = @InputIndex + 1;
        UPDATE @BufferTable SET [Memory] = COALESCE((SELECT ASCII([Char]) FROM @InputTable WHERE [Id] = @InputIndex), 0) WHERE [Id] = @Pointer;
    END

    -- Jump forward past the matching ] if the byte at the pointer is zero.
    ELSE IF @Command = '[' AND COALESCE((SELECT [Memory] FROM @BufferTable WHERE [Id] = @Pointer), 0) = 0
    BEGIN
        SET @Depth = 1;
        WHILE @Depth > 0
        BEGIN
            SET @CodeIndex = @CodeIndex + 1;
            SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex);
            IF @Command = '[' SET @Depth = @Depth + 1;
            ELSE IF @Command = ']' SET @Depth = @Depth - 1;
        END
    END

    -- Jump backwards to the matching [ unless the byte at the pointer is zero.
    ELSE IF @Command = ']' AND COALESCE((SELECT [Memory] FROM @BufferTable WHERE [Id] = @Pointer), 0) != 0
    BEGIN
        SET @Depth = 1;
        WHILE @Depth > 0
        BEGIN
            SET @CodeIndex = @CodeIndex - 1;
            SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex);
            IF @Command = ']' SET @Depth = @Depth + 1;
            ELSE IF @Command = '[' SET @Depth = @Depth - 1;
        END
    END
END;

-- Collects and prints the output
DECLARE @Output VARCHAR(MAX);
SELECT @Output = COALESCE(@Output, '') + [Char]
FROM @OutputTable;

PRINT @Output;
Go

Bu işlem tamamlanan işlem SQL'dir, anladığım ANSI SQL TC değildir. Ama iyi çaba!
alimack

28

https://web.archive.org/web/20110807062050/http://channel9.msdn.com/forums/TechOff/431432-SQL-Turing-Completeness-question

Bu konunun bir tartışmasıdır. Alıntı:

Bu şekilde SQL (örn. SQL92 standardı) tamamlanmadı. Bununla birlikte, Oracle'ın PL / SQL ve SQL Server'ın T-SQL ve diğerleri gibi SQL'den türetilen dillerin çoğu tamamlanıyor.

PL / SQL ve T-SQL kesinlikle programlama dilleri olarak nitelendirilir, SQL92'nin nitelendirilip nitelendirilmediği tartışmaya açıktır. Bazı insanlar, bir bilgisayara ne yapması gerektiğini söyleyen herhangi bir kod parçasının programlama dili olarak nitelendirildiğini iddia eder; bu tanıma göre SQL92 birdir, ancak HTML de öyle. Tanım oldukça belirsiz ve tartışılması gereken anlamsız bir şey.


15

Kesin olarak, SQL şimdi bir turing tam dilidir, çünkü en son SQL standardı "Kalıcı Kayıtlı Modüller" (PSM'ler) içerir. Kısacası, PSM, Oracle'daki PL / SQL dilinin standart sürümüdür (ve mevcut DBMS'nin diğer benzer prosedür uzantıları).

Bu PSM'lerin dahil edilmesiyle SQL tamamlandı


13

Başlangıçta SQL-86'da tanımlandığı gibi bir ANSI select deyimi, her zaman sonlandığından (yalnızca özyinelemeli CTE'ler hariç ve yalnızca uygulamanın keyfi olarak derin özyinelemeyi desteklemesi durumunda) tamamlanmadı. Bu nedenle başka bir turing makinesini simüle etmek mümkün değildir. Saklı yordamlar tamamlanıyor ama hile ;-) bu


1

Oracle'ın PLSQL ve Microsoft'un TSQL'i tamamlanıyor. Oracle'ın select deyiminin kendisi de tamamlanıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.