Điều gì cần một bằng chứng về sự đúng đắn cho một máy đánh chữ thực sự đang được chứng minh?


10

Tôi đã lập trình được vài năm, nhưng tôi không quen với CS lý thuyết. Gần đây tôi đã cố gắng nghiên cứu ngôn ngữ lập trình và là một phần trong đó, kiểm tra và suy luận.

Câu hỏi của tôi là, nếu tôi cố gắng viết một loại suy luận và kiểm tra chương trình cho ngôn ngữ lập trình, và tôi muốn chứng minh rằng máy đánh chữ của tôi hoạt động, chính xác thì tôi đang tìm kiếm bằng chứng gì?

Nói một cách dễ hiểu, tôi muốn trình kiểm tra loại của tôi có thể xác định bất kỳ lỗi nào trong một đoạn mã có thể xảy ra khi chạy. Nếu tôi sử dụng một cái gì đó như Coq để cố gắng chứng minh rằng việc triển khai của tôi là chính xác, thì "bằng chứng chính xác" này sẽ cố gắng thể hiện điều gì?


Có lẽ bạn có thể làm rõ nếu bạn muốn biết (1) liệu việc triển khai của bạn có thực hiện một hệ thống gõ hay (2) liệu hệ thống gõ T của bạn có ngăn được các lỗi bạn nghĩ không? Chúng là những câu hỏi khác nhau. TT
Martin Berger

1
@MartinBerger: Ah, tôi dường như đã bỏ qua sự khác biệt đó. Câu hỏi thực tế của tôi có lẽ là để hỏi cả hai. Bối cảnh là tôi đang cố gắng xây dựng một ngôn ngữ, và vì nó tôi đã viết một máy đánh chữ. Và mọi người yêu cầu tôi sử dụng một thuật toán đã thử và thử nghiệm. Tôi đã quan tâm đến việc xem việc "chứng minh" thuật toán và trình đánh máy mà tôi đang sử dụng là "chính xác" khó đến mức nào. Do đó sự mơ hồ trong câu hỏi của tôi.
Vivek Ghaisas

2
(1) thực sự là một câu hỏi trong xác minh chương trình và ít liên quan đến việc gõ. Chỉ cần cho thấy rằng việc thực hiện của bạn đáp ứng đặc điểm kỹ thuật của nó. Đối với (2), trước tiên, hãy xác định nghĩa lỗi là loại ngay lập tức (ví dụ: các thuật ngữ như thế 2 + "hello"bị 'kẹt'). Một khi điều này được chính thức hóa, bạn có thể chứng minh định lý âm thanh loại. Điều đó có nghĩa là không có chương trình đánh máy nào có thể phát triển thành lỗi loại ngay lập tức. Chính thức, bạn chứng minh rằng nếu một chương trình được và với mọi n : nếu M chạy n bước để trở thành N , thì N không có lỗi loại ngay lập tức. (1/2)MnMnNN
Martin Berger

1
Điều này thường được chứng minh bằng cảm ứng trên và trên đạo hàm của phán đoán đánh máy. (2/2)n
Martin Berger

Cảm ơn bạn! Dựa trên lời giải thích của bạn, có vẻ như (2) thực sự là những gì tôi đang tìm kiếm. Bạn có thể vui lòng làm cho câu trả lời? (Và có thể thêm vào bất kỳ chi tiết nào mà bạn nghĩ có thể hữu ích.) Tôi sẽ chấp nhận đó là câu trả lời! :)
Vivek Ghaisas

Câu trả lời:


10

Câu hỏi có thể được giải thích theo hai cách:

  • Liệu việc thực hiện có thực hiện một hệ thống gõ không?T
  • Liệu hệ thống gõ có ngăn được các lỗi bạn nghĩ không?T

Cái trước thực sự là một câu hỏi trong xác minh chương trình và ít liên quan đến việc gõ. Chỉ cần cho thấy việc triển khai của bạn đáp ứng đặc điểm kỹ thuật của nó, xem câu trả lời của Andrej.

Hãy để tôi nói về câu hỏi sau. Như Andrej đã nói, từ quan điểm trừu tượng, một hệ thống gõ dường như thực thi các thuộc tính trên các chương trình. Trong thực tế, hệ thống gõ của bạn tìm cách ngăn chặn lỗi xảy ra, có nghĩa là các chương trình có thể đánh máy không nên thể hiện lớp lỗi quan tâm. Để cho thấy T làm những gì bạn nghĩ nó cần, bạn phải làm hai việc.TT

  • Đầu tiên, bạn chính thức xác định ý nghĩa của một chương trình có lỗi gõ ngay lập tức . Có nhiều cách để xác định điều này - tùy bạn. Thông thường chúng tôi muốn ngăn chặn các chương trình như 2 + "hello". Nói cách khác, bạn cần xác định một tập hợp con các chương trình, gọi chúng là Bad , chứa chính xác các chương trình có lỗi gõ ngay lập tức.

  • Sau đó, bạn phải chứng minh rằng các chương trình có thể đánh máy không bao giờ có thể phát triển thành các chương trình trong Bad . Hãy chính thức hóa điều này. Đặt phán đoán đánh máy của bạn là Nhớ lại rằng cần được đọc như: chương trình M có kiểu α , giả định các biến miễn phí được đánh máy như được đưa ra bởi môi trường Γ . Thì định lý bạn muốn chứng minh là:ΓM:α.MαΓ

    Định lý. Bất cứ khi nào M N thì N Xấu .ΓM:αMNN

    Làm thế nào để chứng minh định lý này phụ thuộc vào chi tiết của ngôn ngữ, hệ thống gõ và lựa chọn xấu của bạn .

Một cách tiêu chuẩn xác định Xấu là để nói: một thuật ngữ có lỗi loại ngay lập tức nếu nó không phải là một giá trị cũng không có một bước giảm M N . (Trong trường hợp này M thường được gọi là bị mắc kẹt .) Điều này chỉ hoạt động cho ngữ nghĩa hoạt động bước nhỏ. Một cách tiêu chuẩn để chứng minh định lý là chỉ ra rằngMMNM

  • M N cùng ngụ ý Γ N : α . Điều này được gọi là "giảm chủ đề". Nó thường được chứng minh bằng cách cảm ứng đồng thời về đạo hàm của phán đoán đánh máy và độ dài của các mức giảm.ΓM:αMNΓN:α

  • Bất cứ khi nào sau đó M không có trong Bad . Điều này thường cũng được chứng minh bằng cảm ứng về sự phát sinh của phán đoán đánh máy.ΓM:αM

Lưu ý rằng không phải tất cả các hệ thống gõ đều có "giảm chủ đề", ví dụ như các loại phiên. Trong trường hợp này, các kỹ thuật chứng minh tinh vi hơn được yêu cầu.


20

Đó là một câu hỏi hay! Nó hỏi những gì chúng ta mong đợi từ các loại trong một ngôn ngữ gõ.

Đầu tiên lưu ý rằng chúng ta có thể gõ bất kỳ ngôn ngữ lập trình nào với unitype : chỉ cần chọn một chữ cái, nói Uvà nói rằng mọi chương trình đều có loại U. Điều này không phải là rất hữu ích, nhưng nó làm cho một điểm.

eAeAAint

Không có kết thúc về cách biểu cảm của bạn có thể được. Về nguyên tắc, chúng có thể là bất kỳ loại câu lệnh logic nào, chúng có thể sử dụng lý thuyết thể loại và chú thích, v.v. Ví dụ, các loại phụ thuộc sẽ cho phép bạn thể hiện những thứ như "hàm này ánh xạ liệt kê danh sách sao cho đầu ra là đầu vào được sắp xếp". Bạn có thể đi xa hơn, tại thời điểm tôi đang nghe một bài nói chuyện về "logic phân tách đồng thời" cho phép bạn nói về cách các chương trình đồng thời hoạt động với trạng thái chia sẻ. Công cụ ưa thích.

Nghệ thuật của các loại trong thiết kế ngôn ngữ lập trình là một trong những sự cân bằng giữa tính biểu cảm và sự đơn giản :

  • nhiều kiểu biểu cảm hơn cho phép chúng tôi giải thích chi tiết hơn (cho chính chúng tôi và cho trình biên dịch) những gì được cho là đang diễn ra
  • các loại đơn giản dễ hiểu hơn và có thể được tự động hóa dễ dàng hơn trong trình biên dịch. (Mọi người đến với các loại về cơ bản yêu cầu trợ lý bằng chứng và đầu vào của người dùng để kiểm tra loại.)

Đơn giản là không được đánh giá thấp, vì không phải mọi lập trình viên đều có bằng tiến sĩ về lý thuyết ngôn ngữ lập trình.

Vì vậy, hãy để chúng tôi trở lại câu hỏi của bạn: làm thế nào để bạn biết rằng hệ thống loại của bạn là tốt ? Vâng, chứng minh các định lý cho thấy các loại của bạn được cân bằng. Sẽ có hai loại định lý:

  1. Các định lý nói rằng các loại của bạn là hữu ích . Biết rằng một chương trình có một loại nên ngụ ý một số đảm bảo, ví dụ như chương trình sẽ không bị kẹt (đó sẽ là một định lý An toàn ). Một nhóm định lý khác sẽ kết nối các loại với các mô hình ngữ nghĩa để chúng ta có thể bắt đầu sử dụng toán học thực tế để chứng minh mọi thứ về các chương trình của chúng ta (chúng sẽ là các định lý đầy đủ và nhiều định lý khác). Unitype ở trên là xấu vì nó không có định lý hữu ích như vậy.

  2. Các định lý nói rằng các loại của bạn là đơn giản . Một điều cơ bản sẽ là có thể quyết định liệu một biểu thức đã cho có một kiểu đã cho hay không. Một tính năng đơn giản khác là đưa ra một thuật toán để suy ra một loại. Các định lý khác về tính đơn giản sẽ là: một biểu thức có nhiều nhất một loại hoặc một biểu thức có loại chính (nghĩa là loại "tốt nhất" trong số tất cả các loại mà nó có).

Thật khó để cụ thể hơn vì các loại là một cơ chế rất chung chung. Nhưng tôi hy vọng bạn thấy những gì bạn nên chụp cho. Giống như hầu hết các khía cạnh của thiết kế ngôn ngữ lập trình, không có thước đo thành công tuyệt đối. Thay vào đó, có một không gian của thiết kế tích cực, và điều quan trọng là phải hiểu bạn đang ở đâu hoặc muốn ở đâu.


Cảm ơn bạn đã trả lời chi tiết! Tuy nhiên, tôi vẫn không chắc chắn về câu trả lời cho câu hỏi của mình. Để làm ví dụ cụ thể, hãy lấy C - một ngôn ngữ gõ tĩnh với hệ thống loại đủ đơn giản. Nếu tôi viết một máy đánh chữ cho C, làm thế nào tôi chứng minh rằng máy đánh chữ của tôi là "chính xác"? Làm thế nào để câu trả lời này thay đổi nếu thay vào đó tôi đã viết một trình kiểm tra loại cho Haskell, nói rằng HM? Làm thế nào bây giờ tôi sẽ chứng minh "tính đúng đắn"?
Vivek Ghaisas

1
TeATeA

Tôi khuyên bạn nên làm 2. và 3. như một sự kết hợp. Ngoài ra, hãy xem CompCert .
Andrej Bauer

1
TeAeAe

AAe

5

Có một vài điều khác nhau mà bạn có thể có nghĩa là "chứng minh rằng máy đánh chữ của tôi hoạt động". Mà, tôi cho rằng, là một phần của câu hỏi của bạn đang hỏi;)

Một nửa câu hỏi này đang chứng minh rằng lý thuyết loại của bạn đủ tốt để chứng minh bất kỳ tính chất nào về ngôn ngữ. Câu trả lời của Andrej đã khắc phục khu vực này rất tốt. Nửa câu hỏi còn lại là các ngôn ngữ và hệ thống loại của nó đã được sửa lỗi, làm thế nào bạn có thể chứng minh rằng trình kiểm tra loại cụ thể của bạn thực tế thực hiện đúng hệ thống loại? Có hai quan điểm chính tôi có thể thấy ở đây.

Một là: làm thế nào chúng ta có thể tin tưởng rằng một số triển khai cụ thể phù hợp với đặc điểm kỹ thuật của nó? Tùy thuộc vào mức độ đảm bảo mà bạn muốn, bạn có thể hài lòng với một bộ thử nghiệm lớn hoặc bạn có thể muốn một số loại xác minh chính thức, hoặc nhiều khả năng là một hỗn hợp của cả hai . Mặt trái của quan điểm này là nó thực sự làm nổi bật tầm quan trọng của việc thiết lập ranh giới đối với các khiếu nại mà bạn đưa ra: chính xác "chính xác" nghĩa là gì? phần nào của mã được kiểm tra, so với phần nào là TCB giả định? v.v ... Nhược điểm là suy nghĩ quá nhiều về điều này dẫn đến một lỗ thỏ triết lý - tốt, "nhược điểm" nếu bạn không thích những hố thỏ đó.

Quan điểm thứ hai là một toán học hơn về tính chính xác. Khi tiếp xúc với các ngôn ngữ trong toán học, chúng ta thường thiết lập "mô hình" cho "lý thuyết" (hoặc ngược lại) và sau đó cố gắng chứng minh: (a) mọi thứ chúng ta có thể làm trong lý thuyết chúng ta có thể làm trong mô hình và (b) tất cả mọi thứ chúng ta có thể làm trong mô hình chúng ta có thể làm trong lý thuyết. (Đây là SoundnessCompleteđịnh lý. Cái nào phụ thuộc vào việc bạn "khởi nghiệp" từ lý thuyết cú pháp hay từ mô hình ngữ nghĩa.) Với suy nghĩ này, chúng tôi có thể nghĩ về việc triển khai kiểm tra kiểu của bạn như là một mô hình cụ thể cho lý thuyết loại đang nghi vấn. Vì vậy, bạn muốn chứng minh sự tương ứng hai chiều này giữa những gì bạn thực hiện có thể làm và những gì lý thuyết nói rằng bạn sẽ có thể làm. Mặt trái của quan điểm này là nó thực sự tập trung vào việc bạn đã bao quát tất cả các trường hợp góc hay chưa, liệu việc triển khai của bạn đã hoàn thành theo nghĩa không bỏ qua bất kỳ chương trình nào mà nó nên chấp nhận là an toàn kiểu và liệu việc triển khai của bạn có đúng không ý thức không cho phép trong bất kỳ chương trình nào nên từ chối như là đánh máy sai. Nhược điểm là bằng chứng về sự tương ứng của bạn có khả năng khá tách biệt với chính việc thực hiện,


Tôi không chắc mình có thể đồng ý với "mặt trái của quan điểm này là nó thực sự tập trung vào việc bạn đã bao quát tất cả các trường hợp góc hay chưa", đặc biệt nếu mô hình chỉ có âm thanh, nhưng không hoàn chỉnh. Tôi muốn đề xuất một quan điểm khác: đi qua một mô hình là một kỹ thuật chứng minh ngẫu nhiên mà bạn sử dụng vì nhiều lý do, ví dụ như vì mô hình đơn giản hơn. Không có gì trang nghiêm về mặt triết học hơn khi trải qua một mô hình - cuối cùng bạn muốn biết về thực thi thực tế và hành vi của nó.
Martin Berger

Tôi nghĩ rằng "mô hình" và "lý thuyết" có nghĩa theo nghĩa rộng, và wren chỉ nhấn mạnh tầm quan trọng của việc cố gắng thiết lập sự tương ứng hai chiều thông qua "định lý âm thanh + tính hoàn chỉnh". (Tôi cũng nghĩ rằng điều này rất quan trọng và đã bình luận cho bài viết của Andrej.) Đúng là trong một số tình huống, chúng ta chỉ có thể chứng minh một định lý đúng đắn (hoặc một định lý hoàn chỉnh, tùy thuộc vào quan điểm của bạn), nhưng có cả hai hướng trong tâm trí là một hạn chế phương pháp hữu ích.
Noam Zeilberger

1
@NoamZeilberger "Câu hỏi là," Martin nói, "liệu bạn có thể làm cho từ có nghĩa là rất nhiều điều khác nhau."
Martin Berger

Khi tôi tìm hiểu về hệ thống gõ và ngữ nghĩa ngôn ngữ lập trình, tôi nhận thấy rằng các mô hình chỉ là kỹ thuật chứng minh về ngữ nghĩa hoạt động, thay vì tự kết thúc, giải phóng một cách thăng hoa.
Martin Berger

1
Liên kết các mô hình khác nhau thông qua sự đúng đắn và đầy đủ là một phương pháp khoa học quan trọng để chuyển giao cái nhìn sâu sắc.
Martin Berger
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.