Làm thế nào là một máy trạng thái khác với bất kỳ chương trình máy tính khác?


8

Tôi đã thấy một số triển khai "Máy trạng thái" trên github. Theo tôi hiểu, một máy trạng thái lấy đầu vào có thể hoặc không thể chuyển đổi trạng thái của nó thành một trong các tập hợp hữu hạn của các trạng thái khác. Nó khác với bất kỳ chương trình máy tính nào khác?



1
Tại sao đa luồng bị loại trừ? Vẫn còn số lượng trạng thái hữu hạn, chỉ cần chuyển tiếp nhiều hơn từ bất kỳ trạng thái nào.
Điều

2
Âm thanh như tarpit turing . Chỉ vì có thể diễn đạt bất kỳ chương trình nào như vậy, điều này không có nghĩa đó là một hình thức tốt để mô hình hóa nó như thế. Chúng tôi không phải là máy tính, chúng tôi cần lý do về các chương trình, điều này đối với một số chương trình hoạt động tốt khi chúng được thể hiện dưới dạng một máy trạng thái.
CodeInChaos

Câu trả lời:


11

Nếu bạn muốn thực sự là mô phạm, mọi chương trình máy tính đều là Máy trạng thái hữu hạn, bởi vì ngay cả khi bạn chuyển đổi tất cả vật chất trong toàn vũ trụ thành máy tính, nó vẫn sẽ chỉ có bộ nhớ hữu hạn, do đó có một lượng trạng thái hữu hạn và hữu hạn số lượng chuyển tiếp giữa các trạng thái.

Máy trạng thái là các mô hình, giống như Máy tính Lambda, Máy Turing, Máy truy cập ngẫu nhiên, Hệ thống diễn viên, Hệ thống đối tượng, v.v. Một số vấn đề cho vay để được mô hình hóa bởi một bộ máy nhà nước, một số thì không.

Quy trình kinh doanh thường được mô hình hóa thành Máy trạng thái ngay cả trước khi máy tính tồn tại. Họ cho vay tự nhiên theo kiểu suy nghĩ đó.


2
Tôi gặp khó khăn khi thấy lợi ích trong việc gọi một cái gì đó là một máy trạng thái hữu hạn. Có vẻ như quá độc đoán. Nó giống như mô hình một chiếc xe hơi là "một thứ làm công cụ". Về mặt kỹ thuật, nhưng công dụng của nó là gì? Giả sử tôi xây dựng một ứng dụng và tôi nói nó được mô hình hóa như một cỗ máy trạng thái hữu hạn. Tôi thực sự đã nói gì với bạn?
Điều

5
Chà, trong khi bất kỳ chương trình nào về mặt kỹ thuật là một máy trạng thái, khi tôi nói rằng một chương trình đang được mô hình hóa như một máy trạng thái, tôi thường có nghĩa là mã được dự định là phiên âm của một mô hình máy trạng thái trừu tượng - không chỉ là một chương trình xảy ra để trở thành một cỗ máy nhà nước. Điều này cho phép tôi và các lập trình viên khác cùng nhau lý luận về tính đúng đắn trong hai bước - thứ nhất là mô hình trừu tượng và thứ hai là sự tuân thủ của chương trình với mô hình. Máy trạng thái đến trước, sau đó là chương trình. Máy nhà nước có thể là vô giá như một công cụ lý luận!
J Trana

Tôi tiếp tục đọc và suy nghĩ, "Điều này không có nghĩa là tất cả các chương trình là một FSM sao?" Và có bạn nói nó.
johnny

7

Từ quan điểm lý thuyết, nó không khác nhau chút nào. Tất nhiên, từ quan điểm lý thuyết, bạn có thể viết bất kỳ chương trình nào bằng ngôn ngữ lắp ráp và nó cũng sẽ hoạt động tốt.

Mặc dù máy tính mà mã của bạn đang chạy có thể tương đương về mặt toán học với một máy trạng thái rất, rất phức tạp, cũng như bất kỳ chương trình nào khác chạy trên bất kỳ máy tính nào khác, có nhiều vấn đề mà giải pháp thanh lịch nhất của nó là một máy trạng thái hữu hạn đơn giản có trạng thái và chuyển đổi có ý nghĩa cụ thể theo miền mà lập trình viên đã đưa ra (trái ngược với trình biên dịch hoặc nhà thiết kế phần cứng).

Ví dụ, một cách cổ điển để thực hiện các biểu thức chính quy là diễn giải biểu thức chính quy như một đặc tả cho một máy trạng thái hữu hạn, xây dựng một máy như vậy, sau đó cung cấp các chuỗi để chấp nhận hoặc từ chối . Tổng quát hơn, bất cứ khi nào bạn muốn một đối tượng trong chương trình của mình luôn có một trong số các trạng thái hữu hạn và thực thi việc chuyển đổi giữa các trạng thái đó luôn xảy ra theo những cách cụ thể, xây dựng một bộ máy trạng thái có thể là giải pháp tao nhã nhất .


4

một máy trạng thái nhận đầu vào có thể hoặc không thể chuyển đổi trạng thái của nó thành một trong các tập hợp hữu hạn của các trạng thái khác. Nó khác với bất kỳ chương trình máy tính nào khác?

Một số câu trả lời ở đây nhấn mạnh rằng trong vũ trụ hữu hạn (có thể) của chúng ta, mọi thứ đều hữu hạn, tất cả các chương trình máy tính đều chạy trong thời gian hữu hạn, do đó về mặt kỹ thuật, mọi thứ đều là một cỗ máy trạng thái hữu hạn. Đó là "đúng về mặt kỹ thuật (loại đúng nhất)", nhưng cũng hoàn toàn thiếu điểm.

Bản chất là thế này: - Một số chương trình máy tính đòi hỏi nhiều bộ nhớ làm việc hơn khi chúng nhận được đầu vào lớn hơn và phức tạp hơn. Một số thì không.

Nếu bạn nhận ra điều này, bạn sẽ có được một cái nhìn sâu sắc về lý thuyết - thông tin có thể cho phép bạn viết các chương trình hiệu quả và thanh lịch hơn khi bạn gặp phải loại vấn đề nhất định. Nó cũng sẽ cho phép bạn nhận ra loại vấn đề mà điều này có thể áp dụng.

Dưới đây là hai ví dụ về đồ chơi:

Vấn đề 1: Một chương trình nhận được một danh sách các ký tự trên đầu vào tiêu chuẩn. Sau khi tất cả các nhân vật được xử lý, chương trình phải in cho dù số lượng "x" nhân vật trong các đầu vào là lẻ hoặc thậm chí .

Vấn đề 2: Một chương trình nhận được một danh sách các ký tự trên đầu vào tiêu chuẩn. Sau khi tất cả các ký tự được xử lý, chương trình phải in xem số lượng ký tự "x" trong đầu vào có nhỏ hơn , bằng hoặc lớn hơn số ký tự "y" hay không.

Bạn có thể muốn ngừng đọc ngay bây giờ, giải quyết các vấn đề bằng ngôn ngữ lập trình yêu thích của bạn (hoặc chỉ là mã giả) và quay lại sau.

...

Điều quan trọng bạn có thể nhận thấy là như sau: Để thực hiện giải pháp cho vấn đề 1 đúng cách, bạn chỉ cần một bit bộ nhớ. Bạn không phải tính toán số lượng "x" bạn đã xử lý - chỉ cho dù số lượng "x" được xử lý cho đến nay là số lẻ hay số chẵn. Khi bạn gặp một "x" khác, lật bit. Vào cuối chương trình, nhìn vào bit và in câu trả lời.

Đầu vào của bạn có chứa hàng tá ký tự không? Hàng ngàn nhân vật? Nhân vật Googolplex (tất nhiên là nói theo giả thuyết)? Không quan trọng; một chút của bộ nhớ làm việc vẫn sẽ là đủ.

Bạn không thể làm điều tương tự với vấn đề 2. Khi đọc các ký tự, bạn phải nhớ sự khác biệt giữa số lượng "x" 's và "y" đã được xử lý; nếu không bạn không thể in câu trả lời đúng một cách đáng tin cậy. Bạn có thể nhận ra rằng bạn thực sự không cần phải nhớ cả hai số "x" và "y" - chỉ khác biệt của chúng, cho đến nay; một giá trị số nguyên mà bạn sẽ tăng khi gặp "x" khác và giảm khi bạn gặp "y" khác - nhưng vẫn vậy, nếu bạn quyết định sử dụng ví dụ 32 bit bộ nhớ để giữ giá trị này, bạn có thể nhận được đầu vào ( dài vài tỷ ký tự) mà bạn không thể xử lý chính xác với số lượng bộ nhớ giới hạn nhất định.

Đây là những gì chúng tôi muốn nói khi nói rằng vấn đề 1 có thể được giải quyết bằng "máy trạng thái" và vấn đề 2 không thể giải quyết được. Một lượng bộ nhớ hạn chế là đủ cho đầu vào có kích thước bất kỳ.

(Tất nhiên, bạn cũng có thể viết một giải pháp không hiệu quả cho vấn đề 1, trong đó bạn sẽ cố gắng đếm tất cả các "x", và sau đó bạn cũng có thể gặp vấn đề ngoài bộ nhớ. Nhưng sự khác biệt là giải pháp hiệu quả cho vấn đề 1 tồn tại , trong khi giải pháp hiệu quả tương tự cho vấn đề 2 thì không .)

Tại sao điều này quan trọng trong cuộc sống thực?

Đầu tiên, không giống như hai ví dụ đồ chơi này, tình huống khó xử có thể không nằm giữa nghĩa đen một bit và một giá trị nguyên, mà là giữa một số cấu trúc dữ liệu lớn và một số thậm chí lớn hơn. Đôi khi, cấu trúc dữ liệu "thậm chí lớn hơn" không vừa với bộ nhớ máy tính hoặc làm chậm chương trình, thậm chí cho các đầu vào thực tế.

Thứ hai, giải pháp sử dụng máy trạng thái có thể sẽ nhanh hơn nhiều. Ngoài ra, nó sẽ mở rộng tuyến tính với độ dài của đầu vào; nghĩa là, xử lý đầu vào dài hơn 10 lần sẽ cần thời gian gấp 10 lần (trái ngược với thời gian gấp 100 lần). Đó là một thuộc tính mong muốn khi bạn cần xử lý nhiều dữ liệu.

Thứ ba, hạn chế so với việc sử dụng bộ nhớ không giới hạn có ảnh hưởng đến bảo mật . Nếu bạn viết một chương trình chỉ yêu cầu bộ nhớ hạn chế, bạn không phải lo lắng về việc tràn bộ nhớ và làm thế nào chúng có thể bị lạm dụng để làm tổn hại đến bảo mật của toàn hệ thống.

Thứ tư, đây là một phần của chương trình khoa học máy tính tiêu chuẩn ở bất kỳ trường học đàng hoàng nào: ngôn ngữ chính thức , authomata , độ phức tạp tính toán , et cetera. Để hiểu bức tranh lớn hơn đằng sau thiết kế máy tính, trái ngược với chỉ "uhh, tôi đặt một số đoạn mã từ internet, tôi thực sự hy vọng nó hoạt động, nhưng tôi không thể chắc chắn".

Để tận dụng lý thuyết này, bạn không thực sự cần bất kỳ máy móc đặc biệt, khung hoặc thư viện nào ... bạn chỉ cần nhận ra "ồ, phần này của vấn đề thực sự có thể được giải quyết bằng cách sử dụng một lượng bộ nhớ hữu hạn" và viết chương trình của bạn (bằng ngôn ngữ lập trình yêu thích của bạn) phù hợp. Nhưng trong một số trường hợp, tốt hơn là sử dụng một thư viện hiện có, vì vậy bạn không phải phát minh lại bánh xe.


2

Như các câu trả lời khác đã chỉ ra, không có gì đặc biệt về các máy trạng thái. Tuy nhiên, thường có lợi khi tuyên bố rõ ràng rằng chương trình của chúng tôi thực hiện một FSM.

Lập trình bao gồm rất nhiều việc tìm kiếm sự trừu tượng phù hợp cho một vấn đề. Sử dụng một sự trừu tượng ngụ ý nói về mặt trừu tượng hơn là về mặt thực hiện. Nhiều quy trình vốn đã có trạng thái, ví dụ quy trình đăng ký trên trang web hoặc quy trình thanh toán trong ứng dụng thương mại điện tử. Nếu tôi mô hình hóa các quy trình đó, tôi sẽ vẽ các hộp được kết nối bằng mũi tên lên bảng trắng - sơ đồ trạng thái. Ở đây, một máy trạng thái sẽ là một kiểu mẫu thiết kế và nói về máy trạng thái sẽ truyền đạt rõ ràng ý định của tôi với các đồng nghiệp.

Các chương trình bắt buộc vốn có trạng thái nên chúng tôi không luôn chú ý khi chúng tôi giới thiệu trạng thái. Ví dụ, trong ngôn ngữ C, một số cấu trúc ngôn ngữ nhất định như toán tử dấu chấm phẩy đánh dấu một điểm chuỗi thứ hạng, đó là một chuyển đổi trạng thái và thực thi trật tự giữa các hoạt động. Mọi thứ khác nhau trong các môi trường như ngôn ngữ chức năng thuần túy như Haskell hoặc khi sử dụng các giao thức không trạng thái như HTTP. Đột nhiên, bất kỳ trạng thái nào cũng phải trở nên rõ ràng và phrasing rõ ràng thiết kế của chúng tôi như một máy trạng thái có thể làm cho nó dễ quản lý hơn.

Máy trạng thái hữu hạn đóng một vai trò quan trọng trong phân tích cú pháp, vì chúng tương ứng với các biểu thức thông thường. Thực hiện thủ công một số biểu thức chính quy có thể dẫn đến mã cực kỳ nhiều lông, điều tồi tệ nhất của nó thậm chí không đúng. Khi chúng tôi nhận ra rằng chúng tôi đang thực hiện một bộ máy trạng thái, chúng tôi có thể sử dụng nhiều kỹ thuật triển khai đã biết để giúp chúng tôi. Ví dụ: chúng ta có thể làm cho trạng thái rõ ràng và lưu trữ trạng thái hiện tại trong một biến. Ngoài ra, chúng ta có thể làm cho trạng thái ẩn thông qua luồng điều khiển trên ngôn ngữ của chúng ta. Tôi đã thực hiện cả hai trường hợp khác nhau, nhưng nói rằng chúng tôi đang thực hiện một máy trạng thái (có tính năng chuyển trạng thái bị hạn chế, trạng thái bắt đầu, trạng thái kết thúc đã biết, không đệ quy và không có trạng thái ẩn thông qua phân bổ dữ liệu liên tục) thay vì chương trình không bị hạn chế nó dễ thực hiện và hiểu hơn.

Tôi hiếm khi sử dụng một thư viện máy trạng thái, vì tất cả các ngôn ngữ lập trình mà tôi biết giúp dễ dàng diễn đạt chính xác và hiệu quả một máy trạng thái bằng ngôn ngữ đó. Nhưng có những trường hợp ngoại lệ: trong khi automata xác định rất dễ thực hiện, automata không điều kiện là khá không cần thiết, vì máy trạng thái có thể ở nhiều trạng thái cùng một lúc. Sử dụng một thư viện thực hiện NFA hoặc viết lại chúng cho phép tôi bỏ qua những khó khăn này và tập trung vào những thứ thực sự quan trọng.

Ngoài việc sử dụng các máy trạng thái như một thiết kế và các máy trạng thái trong khoa học máy tính và lý thuyết ngôn ngữ, thực sự không có nhiều ứng dụng. Mạch logic nhà nước đến với tâm trí. Việc sử dụng chính của các máy trạng thái cho một lập trình viên là học cách suy nghĩ theo các trạng thái và chuyển trạng thái. Trường hợp chương trình của tôi có trạng thái ngầm? Tôi đã thực hiện đúng tất cả các chuyển đổi nhà nước? Tôi đã bỏ lỡ một cái gì đó và mở ra một trạng thái không hợp lệ? Suy nghĩ như vậy trở nên đặc biệt phù hợp một lần nữa trong lập trình hướng đối tượng, vì các trường thành viên của một đối tượng tương ứng với trạng thái và các phương thức có thể ảnh hưởng đến các chuyển trạng thái. Tôi sẽ ngần ngại thực hiện một cách rõ ràng một máy trạng thái trong một đối tượng, nhưng máy trạng thái vẫn có thể là một mô hình tinh thần phù hợp cho hành vi.

Lý do chính để viết thư viện máy trạng thái là để đảm bảo bạn đã hiểu chủ đề, nhưng trong hầu hết các ứng dụng, bạn sẽ không cần chúng hoặc thay vào đó cuộn chúng lại.

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.