> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/vi/bai-viet-chuyen-sau/31-latex-is-more-powerful-than-you-think-computing-the-fibonacci-numbers-and-turing-completeness.md).

# LaTeX mạnh hơn bạn nghĩ - Tính các số Fibonacci và tính đầy đủ Turing

**Tác giả: Robert Murrish (Tháng 4 năm 2012 (được Overleaf chỉnh sửa vào tháng 4 năm 2023))**

LaTeX là một công cụ mạnh mẽ. Mạnh mẽ đến mức, thực ra, nó có thể được dùng cho nhiều việc hơn là đánh dấu tài liệu. LaTeX là [hoàn chỉnh Turing](https://en.wikipedia.org/wiki/Turing_completeness); tức là, nó có thể được lập trình để tính toán gần như bất cứ thứ gì.

Để minh họa khả năng lập trình đa dụng của LaTeX, chúng ta sẽ xem một ví dụ tính các số Fibonacci đầu tiên. Mặc dù đây không phải là chứng minh cho tính đầy đủ Turing, nhưng nó là một ví dụ tốt về một thuật toán hoàn chỉnh được triển khai trong LaTeX.

### Các số Fibonacci

Mỗi số trong dãy Fibonacci là tổng của hai số hạng trước đó trong dãy, với hai số hạng đầu tiên được định nghĩa là 1 để tạo điểm khởi đầu.

Chúng ta có thể viết một lệnh mới để tính các số này. Hãy bắt đầu bằng cách quyết định một lời gọi đến lệnh mà ta còn chưa viết có thể trông như thế nào:

```latex
\fibonacci{10}
```

Khi lệnh này được gọi từ tài liệu LaTeX của chúng ta, nó sẽ tạo ra một danh sách các `n` số Fibonacci (trong đó `n=10` trong lời gọi ví dụ ở đây). Đây là mã cho `\fibonacci` lệnh (tức là macro LaTeX). Hãy xem nó hoạt động như thế nào.

```latex
\documentclass{article}
\begin{document}

\newcount\temp
\newcount\fone
\newcount\ftwo
\newcount\fcnt

\newcommand{\fibonacci}[1]{%
	\fcnt=#1
	\fone=1
	\ftwo=1
	\temp=0
	\the\fone, \the\ftwo
	\let\next=\fibloop
	\fibloop
}

\def\fibloop{, %
	\temp=\fone
	\fone=\ftwo
	\advance\ftwo by \temp
	\ifnum\fcnt=0
            \let\next=\relax
        \else
            \advance\fcnt by -1
        \fi
	\the\ftwo
	\next
}

(\fibonacci{10})
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Fibonacci+sequence+in+LaTeX\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cbegin%7Bdocument%7D%0A%0A%5Cnewcount%5Ctemp%0A%5Cnewcount%5Cfone%0A%5Cnewcount%5Cftwo%0A%5Cnewcount%5Cfcnt%0A%0A%5Cnewcommand%7B%5Cfibonacci%7D%5B1%5D%7B%25%0A%09%5Cfcnt%3D%231%0A%09%5Cfone%3D1%0A%09%5Cftwo%3D1%0A%09%5Ctemp%3D0%0A%09%5Cthe%5Cfone%2C+%5Cthe%5Cftwo%0A%09%5Clet%5Cnext%3D%5Cfibloop%0A%09%5Cfibloop%0A%7D%0A%0A%5Cdef%5Cfibloop%7B%2C+%25%0A%09%5Ctemp%3D%5Cfone%0A%09%5Cfone%3D%5Cftwo%0A%09%5Cadvance%5Cftwo+by+%5Ctemp%0A%09%5Cifnum%5Cfcnt%3D0%0A++++++++++++%5Clet%5Cnext%3D%5Crelax%0A++++++++%5Celse%0A++++++++++++%5Cadvance%5Cfcnt+by+-1%0A++++++++%5Cfi%0A%09%5Cthe%5Cftwo%0A%09%5Cnext%0A%7D%0A%0A%28%5Cfibonacci%7B10%7D%29%0A%5Cend%7Bdocument%7D)

Trước tiên, chúng ta thiết lập một vài biến sẽ dùng sau. Lệnh `\newcount` cho ta một biến có thể dùng để chứa một số nguyên; ở đây, chúng ta tạo bốn biến: `\fcnt`, `\fone`, `\ftwo` và `\temp`. Cần lưu ý rằng đây không phải là các biến mới; chúng giống như các bí danh cho những bộ đếm hiện có. [Các bộ đếm LaTeX](/latex/vi/dinh-dang/10-counters.md) có thể được dùng trực tiếp như trong `\count0`, `\count1`, v.v., nhưng việc đặt tên cho chúng giúp chúng ta tránh ghi vào một bộ đếm đang được sử dụng. Nếu bạn tò mò, hãy thay một trong các biến trong mã này bằng `\count0`, và số trang sẽ bị sai trong phần còn lại của tài liệu.

Tiếp theo là `\fibonacci` lệnh. Chúng ta tạo nó bằng `\newcommand`, mà ta cung cấp tên, số đối số, và mã TeX để xử lý các đối số. Với lệnh này, chúng ta nhận một đối số duy nhất, số lượng số Fibonacci cần xuất ra. Nội dung của lệnh này đơn giản: chúng ta đặt các giá trị ban đầu cho các biến của mình, in hai số Fibonacci đầu tiên (vì chúng không cần phải tính), rồi gọi `\fibloop`, lệnh này sẽ đảm nhận phần tính toán nặng nhọc cho chúng ta.

Lệnh `\fibloop` được khai báo theo cách tương tự nhưng một phần quan trọng của lệnh này là cách nó lặp. Chúng ta dùng một lệnh gọi là `\next`\fcnt `\fibloop` trong `\fibonacci`được khởi tạo thành `\fibloop` và được dùng bên trong `\fibloop` sẽ lặp lại cho đến khi `\next` được thay đổi bởi mã bên trong lệnh `\fibloop` chính nó. Chúng ta chỉ muốn lặp `n` lần, vì vậy chúng ta dùng một `\ifnum` câu lệnh kiểm tra giá trị của bộ đếm của chúng ta (`\fcnt`) rồi nếu nó chưa đạt giá trị ngưỡng là 0, `\fcnt` được giảm đi mỗi khi vòng lặp lặp lại. Nếu điều kiện được thỏa, chúng ta đặt `\next` sang `\relax`, điều này sẽ ngăn `\fibloop` lặp lại—lệnh cuối cùng `\next` không làm gì cả, và vòng lặp kết thúc.

Các lệnh khác trong khối này tính số Fibonacci tiếp theo trong dãy và cập nhật giá trị các biến để chúng sẵn sàng cho lượt tiếp theo. Lệnh `\the\ftwo` in giá trị của số Fibonacci hiện tại ra tài liệu, và bạn cũng sẽ thấy một dấu phẩy và một khoảng trắng ở đầu `\fibloop` lệnh dùng để ngăn cách từng giá trị.

#### Kết quả

Cách đơn giản nhất để thấy mã này hoạt động là chạy nó trên Overleaf bằng **Mở ví dụ này trong Overleaf** liên kết ở cuối phần hiển thị mã. Dãy Fibonacci tăng rất nhanh, vì vậy bất kỳ `n>44` sẽ dẫn đến tràn số nguyên trong cách triển khai cụ thể này.

### Đi tiếp từ đây?

Như một chứng minh không chính thức rằng LaTeX là hoàn chỉnh Turing, tôi xin trình bày đoạn mã sau đây, là một triển khai nhanh và sơ sài của một [cổng NAND](https://en.wikipedia.org/wiki/NAND_gate):

```latex
\newcount\nanone
\newcount\nantwo

\newcommand{\nand}[2]{%
\nanone=#1
\nantwo=#2
  \ifnum\nanone=\nantwo
    \ifnum\nanone=0\relax 1
      \else 0
    \fi
   \else 1
\fi
}
```

Cổng logic NAND (và cả NOR) có một tính chất thú vị là bất kỳ cổng logic nào khác cũng có thể được tạo từ chỉ một loại cổng này. Từ các cổng logic cơ bản, bạn có thể xây dựng các chốt, flip-flop và bộ nhớ. Đó là những thành phần để tạo nên một máy tính đa dụng. Bạn có thể kiểm tra cổng NAND này với từng một trong bốn đầu vào có thể của nó bằng ví dụ sau mà bạn có thể mở trong Overleaf.

```latex
\documentclass{article}
\begin{document}

\newcount\nanone
\newcount\nantwo

\newcommand{\nand}[2]{%
\nanone=#1
\nantwo=#2
  \ifnum\nanone=\nantwo
    \ifnum\nanone=0\relax 1
      \else 0
    \fi
   \else 1
\fi
}

\nand{0}{0}
\nand{0}{1}
\nand{1}{0}
\nand{1}{1}
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=NAND+gate+in+LaTeX\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cbegin%7Bdocument%7D%0A%0A%5Cnewcount%5Cnanone%0A%5Cnewcount%5Cnantwo%0A%0A%5Cnewcommand%7B%5Cnand%7D%5B2%5D%7B%25%0A%5Cnanone%3D%231%0A%5Cnantwo%3D%232%0A++%5Cifnum%5Cnanone%3D%5Cnantwo%0A++++%5Cifnum%5Cnanone%3D0%5Crelax+1%0A++++++%5Celse+0%0A++++%5Cfi%0A+++%5Celse+1%0A%5Cfi%0A%7D%0A%0A%5Cnand%7B0%7D%7B0%7D%0A%5Cnand%7B0%7D%7B1%7D%0A%5Cnand%7B1%7D%7B0%7D%0A%5Cnand%7B1%7D%7B1%7D%0A%5Cend%7Bdocument%7D)

Biết rằng LaTeX là hoàn chỉnh Turing mở ra cả một thế giới khả năng. Mã như thế này rất phổ biến ở phần hậu trường của LaTeX cho những việc như theo dõi số trang và số hình, và quyết định vị trí đặt các đối tượng nổi. Đây là một công cụ mà bạn có thể tận dụng để đơn giản hóa các bố cục tài liệu phức tạp.

Để kết thúc bài viết này, tôi sẽ để lại cho bạn thêm tài liệu đọc về các ví dụ lập trình trong LaTeX và máy Turing.

#### Ví dụ lập trình LaTeX

* [Tập Mandelbrot trong LaTeX](http://warp.povusers.org/MandScripts/latex.html) . Đặc biệt cảm ơn ví dụ này; đoạn mã này là một ví dụ hữu ích khi tôi viết lệnh Fibonacci của mình.
* [Một máy Turing trong LaTeX: phần tiếp theo](http://pbelmans.ncag.info/blog/2010/12/12/a-turing-machine-in-latex-follow-u/) Lưu ý: Khi chuyển bài viết này sang một hệ thống lưu trữ nội dung khác, chúng tôi nhận thấy trang web được tham chiếu trong bài viết gốc (<http://en.literateprograms.org/Turing_machine_simulator_(LaTeX))> không còn truy cập được nữa, vì vậy chúng tôi đã thay liên kết đó bằng một bài viết tiếp theo của một tác giả khác.
* [Wikibook về các lệnh TeX](http://en.wikibooks.org/wiki/Category:TeX)
* [LaTeX trong một cuộc thi lập trình](http://sdh33b.blogspot.com/2008/07/icfp-contest-2008.html). Một bộ điều khiển tàu thám hiểm sao Hỏa viết bằng LaTeX đã vượt qua các bài dự thi bằng một số ngôn ngữ lập trình phổ biến hơn.

### Máy Turing ở những nơi không ngờ tới

* [Trò chơi Sự sống của Conway là hoàn chỉnh Turing](http://rendell-attic.org/gol/utm/index.htm). Đây là một triển khai của máy Turing.
* [Luật 110](http://en.wikipedia.org/wiki/Rule_110) là một tự động tế bào 1 chiều hoàn chỉnh Turing.
* Minecraft (trò chơi điện tử) là hoàn chỉnh Turing. Một số ví dụ đã được xây dựng, vì vậy liên kết sau đây chỉ đơn giản dẫn đến một [trang kết quả tìm kiếm YouTube liên quan](http://www.youtube.com/results?search_query=minecraft+turing+machine)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/vi/bai-viet-chuyen-sau/31-latex-is-more-powerful-than-you-think-computing-the-fibonacci-numbers-and-turing-completeness.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
