CSS Turing đã hoàn thành chưa?


297

CSS không, trong chừng mực mà tôi biết, Turing hoàn tất. Nhưng kiến ​​thức về CSS của tôi rất hạn chế.

  • CSS Turing đã hoàn thành chưa?
  • Có bất kỳ dự thảo hoặc ủy ban hiện tại nào đang xem xét các tính năng ngôn ngữ có thể kích hoạt tính hoàn chỉnh của Turing nếu hiện tại không?

28
Nó đã được thực hiện, nếu bạn sử dụng eg6. Chúng được gọi là biểu thức CSS và sự đồng thuận là chúng bị phá vỡ khủng khiếp và nguy hiểm. JS được nhúng trong CSS ...
kibibu

13
@Kibibu - Yike! Hãy xóa ý tưởng đó khỏi não tôi trước khi nó tự gấp lại!
DVK

Làm thế nào CSS thể hoàn thành Turing?
SLaks

1
@DVK: bạn thực sự có thể thực hiện một số điều thú vị với chúng - đặc biệt là liên quan đến bố cục độc lập độ phân giải - vẫn còn khó khăn hoặc kỳ quặc trong CSS mà không cần dùng đến các bảng. Tôi nghĩ rằng nếu họ giới hạn nó chỉ là một ngôn ngữ biểu đạt khai báo mà không có tác dụng phụ thay vì cho phép truy cập đầy đủ vào công cụ tập lệnh thì nó sẽ được nhận tốt hơn (và có lẽ nếu bộ webkit xuất hiện trước)
kibibu

5
@SLaks: Đừng đánh giá thấp sức mạnh của HTML5 / CSS3 :)
Niklas B.

Câu trả lời:


385

Bạn có thể mã hóa Quy tắc 110 trong CSS3, do đó, Turing-Complete hoàn thành miễn là bạn xem xét một tệp HTML đi kèm và các tương tác người dùng phù hợp là một phần của lệnh thực thi CSS của CSS. Một triển khai khá tốt có sẵn và một triển khai khác được bao gồm ở đây:

body {
    -webkit-animation: bugfix infinite 1s;
    margin: 0.5em 1em;
}
@-webkit-keyframes bugfix { from { padding: 0; } to { padding: 0; } }

/*
 * 111 110 101 100 011 010 001 000
 *  0   1   1   0   1   1   1   0
 */

body > input {
    -webkit-appearance: none;
    display: block;
    float: left;
    border-right: 1px solid #ddd;
    border-bottom: 1px solid #ddd;
    padding: 0px 3px;
    margin: 0;
    font-family: Consolas, "Courier New", monospace;
    font-size: 7pt;
}
body > input::before {
    content: "0";
}

p {
    font-family: Verdana, sans-serif;
    font-size: 9pt;
    margin-bottom: 0.5em;
}

body > input:nth-of-type(-n+30) { border-top: 1px solid #ddd; }
body > input:nth-of-type(30n+1) { border-left: 1px solid #ddd; clear: left; }

body > input::before { content: "0"; }

body > input:checked::before { content: "1"; }
body > input:checked { background: #afa !important; }


input:not(:checked) +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input::before {
    content: "1";
}
input:not(:checked) +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input {
    background: #fa0;
}


input:checked +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input::before {
    content: "1";
}
input:checked +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input {
    background: #fa0;
}


input:checked +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input::before {
    content: "1";
}
input:checked +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input {
    background: #fa0;
}

input:checked + input:checked + input:checked +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input::before {
    content: "0";
}
input:checked + input:checked + input:checked +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input {
    background: #fff;
}

input:not(:checked) + input:not(:checked) + input:not(:checked) +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input::before {
    content: "0";
}
input:not(:checked) + input:not(:checked) + input:not(:checked) +
        *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
        input {
    background: #fff;
}

body > input:nth-child(30n) { display: none !important; }
body > input:nth-child(30n) + label { display: none !important; }
<p><a href="http://en.wikipedia.org/wiki/Rule_110">Rule 110</a> in (webkit) CSS, proving Turing-completeness.</p>

<!-- A total of 900 checkboxes required -->
<input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/><input type="checkbox"/>


2
Định nghĩa chính thức (đơn giản nhất) của Turing Machine chỉ đơn giản là một bộ trạng thái được đặt, bộ ký hiệu, trạng thái ban đầu, bộ trạng thái chấp nhận và chức năng chuyển tiếp. Không có quây trong đó. Bằng cách tính toán, chúng tôi có nghĩa là ai đó cần phải áp dụng chức năng chuyển đổi một cách trung thực trên băng giống hệt như nhấp chuột trong trường hợp này. Chính thức hơn, một mô hình tính toán có thể được xem như một tập hợp các quy tắc mà ai đó cần tuân theo để thực hiện tính toán. Theo nghĩa đó, tôi nghĩ CSS là Turing-Complete.
Giăng

2
Đoạn mã này dường như không hoạt động (Firefox 61). Tôi thấy một lưới các hộp kiểm trống - không có gì xảy ra nếu bạn kiểm tra chúng.
OrangeDog

2
@John "CSS đã hoàn tất" khiến tôi không yên tâm, nhưng tôi không có vấn đề gì với "CSS hoàn hảo như một vài tảng đá trên bãi biển ". Phát biểu sau có đúng không?
Raphael Schmitz

1
@ R.Schmitz không, trong trường hợp đó, con người đang chọn nơi đặt các tảng đá, vì vậy đó là hệ thống kết hợp giữa đá người + đá đang hoàn thiện. Trong ví dụ CSS ở trên, tab + phím cách là một quá trình lặp lại đơn giản, tương tự như mạch phản hồi. Vì vậy, nếu C ++ hoàn thành việc sử dụng phần cứng máy tính để thực hiện các hướng dẫn, thì không phải nói rằng CSS đã hoàn tất bằng cách sử dụng phím nhấn để thực hiện các hướng dẫn
woojoo666 vào

Đây là CodePen của Quy tắc 110 sử dụng cùng một giải pháp, cộng với các chú thích và một số Sass để giúp DRY mọi thứ: codepen.io/laras126/pen/OYvGZj Tôi đã viết một bài đăng trên blog kèm theo giải thích các khái niệm ở đây: notlaura.com/is-css -turing-hoàn thành
notlaura

89

Một khía cạnh của tính đầy đủ của Turing là vấn đề tạm dừng .

Điều này có nghĩa là, nếu CSS hoàn thành Turing, thì không có chung thuật toán để xác định liệu một chương trình CSS sẽ kết thúc chạy hay lặp mãi mãi.

Nhưng chúng ta có thể rút ra một thuật toán như vậy cho CSS! Đây là:

  • Nếu biểu định kiểu không khai báo bất kỳ hình động nào , thì nó sẽ dừng lại.

  • Nếu nó có hình động, thì:

    • Nếu animation-iteration-countinfinite, và bộ chọn chứa được khớp trong HTML, thì nó sẽ không dừng lại.

    • Nếu không, nó sẽ dừng lại.

Đó là nó. Vì chúng ta vừa giải quyết vấn đề tạm dừng cho CSS, nên CSS không hoàn thành .

.


Daniel Wagner đã đưa ra một điểm mà tôi đã bỏ lỡ trong câu trả lời ban đầu. Anh ấy lưu ý rằng trong khi tôi bao phủ các hình ảnh động , các phần khác của công cụ kiểu như kết hợp bộ chọn hoặc bố cục cũng có thể dẫn đến tính hoàn chỉnh của Turing. Mặc dù rất khó để đưa ra một lập luận chính thức về những điều này, tôi sẽ cố gắng phác thảo lý do tại sao Turing hoàn toàn không có khả năng xảy ra.

Thứ nhất: Các ngôn ngữ hoàn chỉnh Turing có một số cách cung cấp dữ liệu trở lại chính nó , cho dù đó là thông qua đệ quy hoặc lặp. Nhưng thiết kế của ngôn ngữ CSS là không phù hợp với phản hồi này:

  • @mediatruy vấn chỉ có thể kiểm tra các thuộc tính của chính trình duyệt, chẳng hạn như kích thước khung nhìn hoặc độ phân giải pixel. Các thuộc tính này có thể thay đổi thông qua tương tác người dùng hoặc mã JavaScript (ví dụ: thay đổi kích thước cửa sổ trình duyệt), nhưng không chỉ thông qua CSS.

  • ::before::aftercác phần tử giả không được coi là một phần của DOM và không thể được so khớp theo bất kỳ cách nào khác.

  • Bộ kết hợp chọn chỉ có thể kiểm tra các phần tử ở trêntrước phần tử hiện tại, vì vậy chúng không thể được sử dụng để tạo chu kỳ phụ thuộc.

  • Bạn có thể dịch chuyển một yếu tố khi bạn di chuột qua nó , nhưng vị trí chỉ cập nhật khi bạn di chuyển chuột.

Điều đó đủ để thuyết phục bạn rằng , chính nó, không thể hoàn thành Turing . Nhưng còn bố cục thì sao?

Thuật toán bố trí CSS hiện đại rất phức tạp, với các tính năng như FlexboxGrid làm vấy bẩn vùng biển. Nhưng ngay cả khi có thể kích hoạt một vòng lặp vô hạn với bố cục, thật khó để tận dụng điều này để thực hiện tính toán hữu ích. Đó là bởi vì các bộ chọn CSS chỉ kiểm tra cấu trúc bên trong của DOM chứ không phải cách các phần tử này được trình bày trên màn hình. Vì vậy, bất kỳ bằng chứng hoàn chỉnh Turing sử dụng hệ thống bố trí phải phụ thuộc vào bố trí một mình .

Cuối cùng - và đây có lẽ là lý do quan trọng nhất - các nhà cung cấp trình duyệt có mối quan tâm đến việc giữ CSS không hoàn thành Turing . Bằng cách hạn chế ngôn ngữ, các nhà cung cấp cho phép tối ưu hóa thông minh giúp web nhanh hơn cho mọi người. Hơn nữa, Google dành toàn bộ trang trại máy chủ để tìm kiếm các lỗi trong Chrome. Nếu có một cách để viết một vòng lặp vô hạn bằng CSS, thì có lẽ họ đã tìm thấy nó rồi


4
Khi mọi người nói "CSS đã hoàn tất", họ có nghĩa là "CSS, hỗ trợ hoạt hình là Turing Complete". Bạn có thể hạn chế ngôn ngữ lập trình và kết luận chúng không phải là Turing Complete bằng logic của bạn, nhưng bạn sẽ phải chỉ định các hạn chế.
philix

36
Tôi nghĩ rằng câu trả lời này đang sử dụng một định nghĩa hài hước về "tạm dừng" - chắc chắn không phải là câu tôi muốn nếu tôi đang đặt câu hỏi, ít nhất là. Bạn dường như sử dụng "tạm dừng" để có nghĩa là "có một thời gian tại đó các thuộc tính được tính toán cho mỗi phần tử ngừng thay đổi"; nhưng tôi muốn "tạm dừng" có nghĩa là "thuật toán chuyển đổi CSS khai báo thành các thuộc tính được tính toán của tất cả các phần tử kết thúc chạy". Với định nghĩa sau, có vẻ như cần phải tranh luận nhiều hơn đáng kể so với chỉ "không có hoạt hình".
Daniel Wagner

4
Logic của bạn là ngược ở đây. Tính đầy đủ của Turing ngụ ý rằng việc tạm dừng là không thể giải quyết được không có nghĩa là tạm dừng là không thể giải quyết được ngụ ý Turing đầy đủ.
asmeker

3
@LambdaFerry vấn đề tạm dừng cho CSS là gì? Tôi không tin một điều như vậy tồn tại. Vấn đề tạm dừng chỉ liên quan đến máy móc. Mô hình tính toán mạnh mẽ nhất mà chúng ta có ngày nay là Turing Machines. Máy tính của bạn mạnh như một máy Turing (bộ nhớ vô hạn). CSS không thể được định nghĩa là một máy. Có lẽ bạn có thể định nghĩa công cụ CSS của trình duyệt là một máy, nhưng ngay cả khi đó nó chỉ có thể mạnh như TM. Câu lệnh "tạm dừng vấn đề cho CSS " chỉ đơn giản là không có ý nghĩa gì, trừ khi CSS đã trở thành một máy tự động mới trong hệ thống phân cấp của Chomsky.
Mike Shi

3
@LambdaFerry Bạn đang hiểu nhầm một bằng chứng về sự không hoàn hảo sẽ như thế nào. Chúng tôi biết rằng vấn đề tạm dừng là không thể giải quyết được bằng một TM. Bằng chứng ban đầu dường như đưa ra yêu cầu bởi vì CSS có thể giải quyết vấn đề tạm dừng mà nó không hoàn thành. Nếu CSS thực sự có thể giải quyết vấn đề tạm dừng, thì CSS mạnh hơn Turing Machine vì nó có thể tính toán một thứ mà TM không thể. Chúng tôi biết (theo Luận án Turing của Giáo hội), rằng một cỗ máy không thể được chế tạo mạnh hơn TM / Công cụ Lambda. Do đó, đây là một mâu thuẫn và tuyên bố ban đầu của bạn không chính xác.
Kim cương Isaac

32

Theo bài viết này, nó không phải là . Bài báo cũng lập luận rằng nó không phải là một ý tưởng tốt để làm cho nó một.

Để trích dẫn từ một trong những ý kiến:

Vì vậy, tôi không tin rằng CSS đã hoàn tất. Không có khả năng để xác định một chức năng trong CSS. Để một hệ thống được hoàn thiện, phải viết một trình thông dịch: một chức năng diễn giải các biểu thức biểu thị các chương trình để thực thi. CSS không có biến nào có thể truy cập trực tiếp đến người dùng; do đó, bạn thậm chí không thể mô hình hóa cấu trúc đại diện cho chương trình được diễn giải bằng CSS.


4
CSS không thể thực thi được bằng mọi cách. Người viết bình luận được trích dẫn dường như không hiểu điều đó. : - \
Ryan Trước

33
CSS là một bộ hướng dẫn cho bộ xử lý (công cụ bố trí). Điều gì không "thực thi" về nó?
DVK

47
Turing-đầy đủ không chỉ là về nếu bạn có thể viết chương trình theo cách bạn muốn hoặc một niềm tin. Nó là một tính chất toán học về khả năng tính toán. Vì vậy, bạn không thể tin hay không CSS là Turing-Complete, bạn cần một bằng chứng. Trong trường hợp này, do quy tắc 110, CSS hoàn thành Turing.
Mikaël Mayer

15
@ MikaëlMayer - như đã lưu ý trong nhiều bình luận trong câu trả lời "110", yêu cầu người dùng thực hiện một hành động. Nếu các hành động của người dùng được yêu cầu, CSS mà không có người dùng thì KHÔNG hoàn thành Turing
DVK

1
@DVK các phím bấm lặp được yêu cầu trong ví dụ CSS 110 không hoàn toàn là "hành động" của người dùng, chúng có thể được thực hiện bằng một mạch kỹ thuật số lặp lại. Các máy turing thực tế yêu cầu một số loại phần cứng điện để điều khiển thực thi, vì vậy tôi không thấy nó khác biệt như thế nào
woojoo666

6

Tính đầy đủ của Turing không chỉ là về "xác định chức năng" hay "có ifs / vòng / etc". Ví dụ: Haskell không có "vòng lặp", lambda-tính toán không có "ifs", v.v ...

Ví dụ: trang web này: http://experthuman.com/programming-with-noth . Tác giả sử dụng Ruby và tạo một chương trình "FizzBuzz" chỉ với các lần đóng (không có chuỗi, số hoặc bất cứ thứ gì tương tự) ...

Có những ví dụ khi mọi người tính toán một số hàm số học trên Scala chỉ sử dụng hệ thống loại

Vì vậy, theo tôi, CSS3 + HTML đã hoàn tất (ngay cả khi bạn không thể thực hiện bất kỳ tính toán thực sự nào sau đó mà không trở nên điên rồ)


11
Haskell và lambda-caclculus có đệ quy. Có CSS ​​không? Bạn phải điên lên để thực hiện bất kỳ tính toán thực sự nào trong Malbolge; trong CSS, không quan trọng bạn điên đến mức nào: nó sẽ không hoạt động, CSS không hoàn thiện và đó không phải là vấn đề quan điểm.
JMCF125

11
Xin lỗi, tôi không thể tìm thấy bất kỳ bình luận nào khác của bạn trong trang này. Nhưng như đã lưu ý trong câu trả lời được chấp nhận, đó là Turing-Complete "(...) miễn là bạn coi (...) các tương tác của người dùng là một phần của lệnh thực thi của CSS". Và tôi thì không.
JMCF125

20
Không có ý định gây khó chịu, sự hoàn thiện của Turing không đáp ứng với ý kiến ​​của bất kỳ ai.
trisweb

5
@ MaurícioSzabo Không, CSS3 cộng với HTML cộng với một con người liên tục đẩy mạnh mô phỏng là Turing hoàn tất.
Tiên nữ Lambda

4
@LambdaFerry Điều đó cũng đúng với mọi máy Turing vật lý.
Miles Rout

5

Vấn đề cơ bản ở đây là bất kỳ máy nào được viết bằng HTML + CSS không thể đánh giá vô số bước (nghĩa là không thể có đệ quy "thực") trừ khi mã dài vô hạn. Và câu hỏi máy này sẽ đạt cấu hình Htheo ncác bước hoặc ít hơn luôn luôn có thể trả lời nđược nếu là hữu hạn.


1
Tôi không thấy nơi nào trong Turing Machine yêu cầu khả năng xử lý các vòng lặp vô hạn được chỉ định. Điểm thứ hai của bạn dường như không hợp lệ. Mặc dù Turing đã sử dụng Máy Turing của mình để chứng minh các vấn đề về tính toán, nhưng các quy tắc này, giống như vấn đề tạm dừng, không xác định liệu máy có phải là máy Turing hay không. Nếu Máy Turing bao gồm các giả thuyết này là yêu cầu thì anh ta không thể sử dụng máy Turing để chứng minh chúng.
Adam Davis

4
@AdamDavis Đó là một lập luận hoàn toàn hợp lệ: nếu một thuật toán tồn tại giải quyết vấn đề tạm dừng cho một chủ nghĩa hình thức hoàn chỉnh Turing, điều đó tương đương với việc giải quyết vấn đề tạm dừng nói chung. Tất nhiên, điều này đã được chứng minh là không thể, điều đó có nghĩa là nếu vấn đề tạm dừng có thể được giải quyết cho một chủ nghĩa hình thức nhất định, thì chủ nghĩa hình thức đó không được hoàn thành. Do đó, tất cả các hình thức chỉ có thể đánh giá một số bước hữu hạn không thể bao gồm Turing-Complete, bao gồm CSS.
00dani

3
Không phải B thì A! Đó là nếu không phải B thì không phải A ! Các cựu đang khẳng định hậu quả , mà bạn chỉ ra chính xác là sai. Cái sau, đối số của contrapositive , là những gì tôi sử dụng và hợp lệ. Lưu ý việc sử dụng cẩn thận phủ định trong nhận xét cuối cùng của tôi - Tôi đã xây dựng nó một cách cụ thể để tránh sai lầm đó.
Tiên nữ Lambda

1
@ woojoo666 Không. Có thể chuyển đổi trạng thái theo một bộ quy tắc không giống như hoàn thành Turing. Không có gì chỉ có thể cho một số bước hữu hạn có thể được hoàn thành. Nếu tập hợp các quy tắc biến đổi chỉ có thể được áp dụng một số lần hữu hạn cho câu hỏi "Hệ thống có bao giờ đạt đến trạng thái Hkhông?" luôn luôn có thể quyết định và do đó nó không hoàn thành Turing. Việc thực hiện một thiết bị tự động di động chỉ có thể thực hiện một số lần lặp hữu hạn không bao giờ có thể hoàn thành.
Henrik Sommerland

1
Và, vâng, CSS cũng đang hoàn thiện [cần dẫn nguồn]
Andrea Lazzarotto

4

Đây Câu trả lời là không chính xác bởi vì nó trộn mô tả về UTM và UTM bản thân (Universal Turing Machine).

Chúng tôi có câu trả lời tốt nhưng từ quan điểm khác nhau và nó không hiển thị sai sót trực tiếp trong câu trả lời hàng đầu hiện tại.


Trước hết chúng ta có thể đồng ý rằng con người có thể làm việc như UTM. Điều này có nghĩa là nếu chúng ta làm

CSS + Human == UTM

Sau đó, CSSmột phần là vô ích vì tất cả công việc có thể được thực hiện bởi Humanai sẽ làm phần UTM. Đạo luật nhấp có thể là UTM, vì bạn không nhấp ngẫu nhiên mà chỉ ở những nơi cụ thể.

Thay vì CSS tôi có thể sử dụng văn bản này ( Quy tắc 110 ):

000 -> 0
001 -> 1
010 -> 1
011 -> 1
100 -> 0
101 -> 1
110 -> 1
111 -> 0

Để hướng dẫn hành động của tôi và kết quả sẽ giống nhau. Điều này có nghĩa là văn bản UTM này? Không, đây chỉ là đầu vào (mô tả) mà các UTM (người hoặc máy tính) khác có thể đọc và chạy. Nhấp vào là đủ để chạy bất kỳ UTM.


Phần quan trọng mà CSS thiếu là khả năng thay đổi trạng thái của chính nó theo cách tùy ý, nếu CSS có thể tạo ra các nhấp chuột thì đó sẽ là UTM. Lập luận rằng các nhấp chuột của bạn là "quây" cho CSS là không chính xác vì "quây" thực sự cho CSS là Công cụ Bố cục chạy nó và nó đủ để chứng minh rằng CSS là UTM.


Quy tắc 110 là UTM. Văn bản của bạn là một mô tả (có thể hơi không đủ) của Quy tắc 110, vì vậy, có văn bản đó là một (đại diện của một) UTM.
OrangeDog

"Nếu CSS có thể tạo ra các nhấp chuột" Tôi sử dụng rất nhiều bộ vi điều khiển AVR trong các dự án của mình. Bạn có thể sử dụng đồng hồ bên trong, giới hạn ở 8 MHz. Ngoài ra, bạn có thể kết nối một tinh thể bên ngoài và lên đến 20 MHz. Ngoài ra, tôi cũng có thể chỉ cung cấp một đồng hồ hoàn toàn bên ngoài để nó thậm chí không phải là phần cứng cpu thực sự điều khiển tinh thể. Có nghĩa là tôi thực sự có thể nối một công tắc và một đoạn mạch để phát hành nó, và hoàn toàn sử dụng nó như một chiếc đồng hồ khi tôi nhấn nút. Điều đó có nghĩa là nó sẽ ngừng hoàn thành nếu tôi làm điều đó?
Cedric Mamo

1
@CedricMamo Nhưng các nhấp chuột của bạn thay đổi trạng thái và bạn chỉ cần nhấp vào đúng chỗ khác, nó sẽ không hoạt động. Nhìn chính xác vào eli.fox-epste.in/rule110-full.html Tôi có thể nhấp vào BẤT K cell ô nào, nếu CSS bị vô hiệu hóa tôi vẫn nhấp vào các ô chính xác và có UTM. Nếu tất cả những gì bạn làm sẽ là nhấp vào một nút "tiếp theo" thì thực sự CSS sẽ là UTM, nhưng để có một cái gì đó giống như bạn cần có một số lệnh gọi cho mỗi lần nhấp vào nút và như chúng ta biết là JS IS UTM. Đối với CSS, bạn cần có một cái gì đó sẽ diễn giải chính xác kết quả và trạng thái cập nhật.
Yankes

1
@CedricMamo có liên kết nào không? Ngay bây giờ tôi nhìn vào một vài ví dụ từ đó nhưng nó không hoạt động với tôi. Nhìn chung, nếu tôi hiểu chính xác CSS sẽ thay đổi mức độ hiển thị của một số hộp kiểm và bạn sử dụng các tab để điều hướng đến cái tiếp theo và ở đây chúng tôi lại ẩn UTM không phải là CSS, vì khi bạn yêu cầu trình duyệt tính toán vị trí hợp lệ tiếp theo để điều hướng và Để đánh lừa nó, RẤT NHIỀU mã phức tạp, cái này sử dụng CSS nhưng nhiều hơn thế. Điều này có nghĩa là bạn chứng minh rằng trình duyệt của bạn là UTM chứ không phải CSS.
Yankes

1
@CedricMamo Nhưng Cellata automata có định nghĩa riêng của nó là một vòng lặp, khi quá trình chuyển đổi trạng thái được thực hiện thì nó lại chạy và một lần nữa, v.v. Nếu chúng ta loại bỏ nó và chỉ để lại quá trình chuyển đổi trạng thái này thì automata này sẽ không còn là UTM nữa. Điều này sẽ hoàn toàn giống với CSS. Chúng ta có thể xác định hai bước trong CA, R- trạng thái đọc và Wtrạng thái ghi, CA bình thường thực hiện chuỗi vô hạn RWRWRWRW...trong trường hợp CSS chúng ta chỉ có Rvà chúng ta không có Wvì nó sửa đổi những thứ mà nó không thể đọc, chỉ khi chúng ta thêm B- hành động trình duyệt sau đó chúng ta có thể có RBRBRBR...nhưng sau đó BBBBBBlà trên UTM của chính nó.
Yankes

-28

CSS không phải là một ngôn ngữ lập trình, vì vậy câu hỏi về sự hoàn thiện là một câu hỏi vô nghĩa. Nếu các phần mở rộng lập trình được thêm vào CSS như trường hợp trong IE6 thì sự tổng hợp mới đó là một điều hoàn toàn khác.

CSS chỉ đơn thuần là một mô tả về phong cách; nó không có logic nào, và cấu trúc của nó phẳng.


1
Ngoài ra (IIRC), có một sự mơ hồ về kiểu nào được ưu tiên khi nhiều kiểu xung đột (trùng lặp) được sử dụng. Và sau đó, có những cách hơi khác nhau mà các trình duyệt khác nhau thực hiện / diễn giải các kiểu đánh dấu để xử lý.
David R Tribble

70
"CSS không phải là ngôn ngữ lập trình, vì vậy câu hỏi về sự hoàn thiện là một câu hỏi vô nghĩa." Câu Tautological là tautological.
Adam Davis

3
Hãy xem ngôn ngữ lập trình Prolog nếu bạn tự hỏi tại sao câu trả lời của bạn lại bị hạ thấp quá nhiều.
edwin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.