- Chỉ với
find và mkdir của GNU, có thể tạo vòng lặp và chuyển đổi trạng thái bằng cách tận dụng việc tạo thư mục và thứ tự duyệt, biến tổ hợp các tiện ích tệp đơn giản thành một mô hình tính toán
- Chứng minh được thực hiện thông qua việc triển khai tag system, còn chứng minh dựa trên Rule 110 ở phiên bản đầu đã được sửa do vấn đề xử lý lặp vô hạn
- Vòng lặp cơ bản có cấu trúc trong đó
find x -execdir mkdir x/x \; liên tục phát hiện các thư mục mới; nếu thêm -regex thì cũng có thể rẽ nhánh điều kiện kiểu FizzBuzz
- Triển khai tag system biểu diễn trạng thái bằng đường dẫn tệp và dùng back-reference để sao chép phần còn lại sau khi loại bỏ
m ký tự đầu
- POSIX để hành vi khi tệp được thêm vào thư mục đang được tìm kiếm là unspecified, nên kết luận phụ thuộc vào hành vi quan sát được của các công cụ GNU và môi trường được nêu
Xây dựng mô hình tính toán bằng GNU find và mkdir
- Mục tiêu là chứng minh rằng một hệ thống chỉ có các lệnh
find và mkdir của GNU là Turing-complete
- Chứng minh được tiến hành bằng cách triển khai tag system
- Luồng tổng thể đi theo thứ tự: xây dựng vòng lặp, FizzBuzz, rồi triển khai tag system
- Lỗi trong chứng minh dựa trên Rule 110 ở phiên bản đầu ngày 2/8/2024 đã được sửa, và phiên bản hiện tại chuyển sang triển khai tag system
- Phiên bản đầu có vấn đề là không xử lý được số lần lặp vô hạn
- Bài báo liên quan Turing Completeness of GNU find: From mkdir-assisted Loops to Standalone Computation đã được chấp nhận tại FUN with Algorithms 2026
Vòng lặp được tạo ra bởi việc tạo thư mục
- Đoạn mã sau tạo thư mục đệ quy và đi vào vòng lặp vô hạn
mkdir x
find x -execdir mkdir x/x \;
find x liệt kê các tệp bên dưới x, bao gồm cả chính x
- Khi
x được liệt kê, mkdir tạo x/x, và ở vòng lặp tiếp theo của find, x/x mới được tạo sẽ được đưa vào
- Quá trình này lặp lại, liên tục tạo ra các đường dẫn như
x/x/x, x/x/x/x
- Có thể dùng tùy chọn
-maxdepth để giới hạn độ sâu tạo ra
mkdir x
find x -maxdepth 3 -execdir mkdir x/x \;
- Ví dụ này tạo
x/x/x/x/x rồi kết thúc
FizzBuzz triển khai bằng find -regex
- Tùy chọn
-regex của find có thể lọc tên tệp sẽ trở thành đối tượng của các hành động tiếp theo
- Kết hợp bộ lọc này với vòng lặp để triển khai FizzBuzz, xác định số lượng
x/ có phải là bội số của 3, 5, hoặc 15 hay không
- Ví dụ dùng
-regextype posix-extended để dễ đọc, nhưng có thể xem là cùng cách này cũng làm được với các cú pháp biểu thức chính quy khác
mkdir -p d/x
find d/x -regextype posix-extended -regex 'd(/x){0,29}' -execdir mkdir x/x \;
find d -regextype posix-extended \
-regex 'd((/x){15})+' -printf "FizzBuzz\n" -o \
-regex 'd((/x){5})+' -printf "Buzz\n" -o \
-regex 'd((/x){3})+' -printf "Fizz\n" -o \
-regex 'd(/x)+' -printf "%d\n"
- Dòng thứ hai tạo một đường dẫn bên dưới
d với 30 x liên tiếp
- Dòng thứ ba in
FizzBuzz nếu số lượng x là bội số của 15, Buzz nếu là bội số của 5, Fizz nếu là bội số của 3, còn lại thì in độ sâu tính từ d
- Có thể xem kết quả chạy trong ví dụ OneCompiler
Chứng minh Turing-complete bằng tag system
- Tag system gồm
(m, A, P)
m là một số nguyên dương
A là bảng chữ cái hữu hạn chứa ký hiệu dừng H
P là quy tắc sinh cho từng ký tự trong bảng chữ cái
- Khi có chuỗi ban đầu, hệ thống lặp lại quá trình sau
- Dừng nếu độ dài chuỗi nhỏ hơn
m hoặc ký tự đầu tiên là H
- Nếu không, thêm
P(x) ứng với ký tự đầu tiên x vào cuối chuỗi
- Xóa
m ký tự đầu
- Người ta đã biết rằng tag system với
m=2, |A|=576 là máy Turing phổ dụng; hệ thống có thể chạy tag system cỡ này là Turing-complete
- Ví dụ triển khai thực tế dùng 2-tag system đơn giản trên Wikipedia với
m=2, |A|=4
Cách dùng đường dẫn tệp làm trạng thái
- Ý tưởng cốt lõi là liên tục nối trạng thái tiếp theo vào sau đường dẫn tệp biểu diễn trạng thái
- Dùng
_ làm dấu phân tách giữa các trạng thái
- Ví dụ:
_/b/a/a/_
- Nếu trạng thái tiếp theo là
a/c/c/a thì đường dẫn trở thành _/b/a/a/_/a/c/c/a/_
- Trong khi chạy, cấu hình sao cho trong một thư mục không có nhiều hơn một tệp
- Việc triển khai tiếp tục thêm trạng thái kế tiếp cho đến khi gặp ký hiệu dừng hoặc độ dài chuỗi trở thành không quá
m
- Biểu thức điều kiện của
find hoạt động chủ yếu theo ba phần
- Kiểm tra điều kiện dừng
- Dùng back-reference để sao chép phần còn lại sau khi loại bỏ
M ký tự đầu từ trạng thái trước đó
- Áp dụng quy tắc sinh cho
a, b, c
- Các quy tắc sinh ví dụ như sau
M=2
PROD_A="c/c/b/a/H"
PROD_B="c/c/a"
PROD_C="c/c"
- Kết quả chạy kỳ vọng là
_/H/c/c/c/c/c/c/a/_
- Kết quả chạy đó cũng được cung cấp dưới dạng ví dụ OneCompiler
Back-reference và khả năng mở rộng
- Triển khai FizzBuzz dùng biểu thức chính quy thông thường, nhưng triển khai tag system dùng back-reference
\2
- Nhờ back-reference, có thể sao chép phần của trạng thái trước sau khi bỏ qua
m ký tự đầu tiên
- Cấu trúc này có thể mở rộng sang bảng chữ cái có kích thước hằng số lớn hơn
- Nếu thiếu ký tự có thể dùng nhiều hơn một ký tự cho mỗi tên tệp để xử lý
- Vì vậy đi đến kết luận rằng tổ hợp
find + mkdir là Turing-complete
Ràng buộc POSIX và môi trường chạy
- Do giới hạn độ dài đường dẫn tệp, có khả năng không chạy được automata có kích thước tùy ý, nhưng mã được trình bày được cấu hình để không truyền trực tiếp đường dẫn tệp có độ dài tùy ý cho
mkdir
- Trong thử nghiệm,
find vẫn hoạt động với đường dẫn dài hơn 30000 ký tự, và không tìm thấy giới hạn riêng nào
- Không có đảm bảo theo đặc tả POSIX
- Tài liệu POSIX
find nêu rõ rằng khi tệp được thêm vào thư mục đang được tìm kiếm, hành vi là unspecified
- Chưa kiểm chứng hành vi của các công cụ ngoài GNU
- Môi trường được sử dụng như sau
find (GNU findutils) 4.8.0
mkdir (GNU coreutils) 8.32
Linux DESKTOP-5JU1LI7 5.15.153.1-microsoft-standard-WSL2 #1 SMP Fri Mar 29 23:14:13 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
1 bình luận
Ý kiến trên Hacker News
Ngay đầu trang đã ghi rõ thế này: tuyên bố tính Turing hoàn chỉnh của find + mkdir đã bị rút lại
Có ghi rằng do có lỗi trong chứng minh nên họ rút lại tuyên bố rằng đã chứng minh được find + mkdir là Turing hoàn chỉnh, và bảo xem https://news.ycombinator.com/item?id=41117141
Họ nói sẽ cập nhật bài viết nếu có thể sửa được chứng minh
Có thể dùng cái này để triển khai Folders không?
https://www.danieltemkin.com/Esolangs/Folders/
Các mục thư mục vẫn chiếm chỗ trong MFT, chỉ là Explorer chỉ tính các block được cấp phát ở nơi khác nên không hiện ra thôi
Nếu cứ tiếp tục tạo thư mục rỗng thì MFT sẽ lớn dần lên và cuối cùng vẫn gặp vấn đề về dung lượng
Các tệp nhỏ cũng tương tự: một tệp văn bản rỗng sẽ hiện kích thước 0 byte · dung lượng đĩa 0 byte, và kể cả khi thêm khoảng 400 byte thì dữ liệu vẫn nằm trong mục thư mục của MFT đã được cấp phát sẵn nên Explorer vẫn hiện dung lượng đĩa là 0
Nếu tăng dữ liệu lên gấp đôi thì các block đĩa sẽ được cấp phát, khi đó sẽ hiện độ dài 800 byte, dung lượng đĩa 4.096 byte, và dù giảm lại còn 400 byte thì dữ liệu cũng không quay lại MFT nên vẫn tiếp tục chiếm 4.096 byte
Dù vậy điều này cũng không làm giảm đi sự thích thú với thành quả rất tuyệt này
Tôi không hiểu điều này cho thấy tính Turing hoàn chỉnh như thế nào
Việc cài đặt automaton quy tắc 110 có vẻ vừa bị giới hạn về bề rộng, vừa bị giới hạn về số lần lặp
Số trạng thái cho một bề rộng nhất định là hữu hạn nên không Turing hoàn chỉnh, và vì luôn kết thúc nên cũng không Turing hoàn chỉnh
Có thể viết một bản cài đặt quy tắc 110 với bề rộng và độ sâu tùy ý, tức là có thể mở rộng vô hạn, hay không?
Máy tính thực tế cũng dùng bộ nhớ hữu hạn chứ không phải băng vô hạn, nên dù là ngôn ngữ hay phương pháp nào thì cũng không thỏa điều kiện đó
Họ nói sẽ cập nhật bài viết nếu có thể sửa được chứng minh
Đã bị rút lại
Có ghi rằng: “Do có lỗi trong chứng minh, tôi rút lại tuyên bố rằng đã chứng minh được find + mkdir là Turing hoàn chỉnh”
Tôi cứ nghĩ sẽ thấy một dạng lambda calculus thú vị, nhưng thực ra nó chỉ dựa vào bộ phân tích cú pháp regex của find để tính toán
Một ví dụ đáng nhớ là http://realgl.blogspot.com/2013/08/battlecode.html, hãy xem phần “Regular Expression Pathfinding”
Có vẻ chứng minh này sẽ đơn giản hơn nhiều nếu dùng tag system (https://en.m.wikipedia.org/wiki/Tag_system) thay vì cellular automata
Không có cách triển khai nào có thể là vô hạn, nhưng trong trường hợp này giá trị PATH_MAX thường là 4096 có vẻ đặc biệt thấp
Trên GNU, có vẻ nó vẫn hoạt động với độ dài đường dẫn lớn hơn 4096
apparently họ nói đã thử tới độ dài đường dẫn 30k
Phần mềm/dịch vụ triển khai hoặc tiêu thụ regex (RE, RegExp), hoặc các thành phần trong một chuỗi phần mềm/dịch vụ như vậy, về mặt tiềm năng có thể Turing hoàn chỉnh
Trong bối cảnh đó, nếu bảo mật là điều quan trọng thì nên kiểm tra xem chúng có tính Turing hoàn chỉnh hay không
Để có được tính Turing hoàn chỉnh thì cần 2 stack
Tuy vậy, nhiều thư viện regex hỗ trợ nhiều tính năng hơn rất nhiều so với “regex” đơn thuần
find của tôi không chỉ có thể chứng minh là Turing hoàn chỉnh, mà còn không phải Turing tarpit và được biên dịch thành mã máy native