Bằng chứng chính xác của mã bao giờ đi chính thống? [đóng cửa]


14

Tất cả trừ những chương trình tầm thường nhất đều chứa đầy lỗi và vì vậy bất cứ điều gì hứa hẹn sẽ loại bỏ chúng đều vô cùng lôi cuốn. Hiện tại, bằng chứng chính xác là mã cực kỳ bí truyền, chủ yếu là do khó học điều này và nỗ lực thêm để chứng minh một chương trình chính xác. Bạn có nghĩ rằng mã chứng minh sẽ bao giờ cất cánh?

Câu trả lời:


8

Không thực sự theo nghĩa đó, nhưng lập trình chức năng thuần túy là tốt trong lĩnh vực này. Nếu bạn sử dụng Haskell, có khả năng chương trình của bạn là chính xác nếu mã biên dịch. Ngoại trừ IO, một hệ thống loại tốt là một trợ giúp tốt.

Ngoài ra lập trình để ký hợp đồng có thể hữu ích. Xem Hợp đồng mã Microsoft


6
Xin lỗi - Tôi chưa thực hiện nhiều "thế giới thực" Haskell, nhưng tôi đã thực hiện đủ các bài tập hướng dẫn trong nhiều kiếp. Chỉ vì nó biên dịch không có nghĩa là nó có khả năng hoạt động. So với ví dụ Ada (được chọn vì nó là ngôn ngữ mệnh lệnh được gõ tĩnh), tôi muốn nói Haskell dễ hơn một chút, nhưng chủ yếu là vì nó ngắn gọn hơn (độ phức tạp chu kỳ thấp hơn). Khi giao dịch với đơn vị IO, có những phiền toái có thể khiến Haskell trở nên khó khăn hơn để trở nên đúng đắn - nó chỉ đủ khác với phong cách bắt buộc là có những điều nó không thể làm một cách tự nhiên.
Steve314

Trên "không thể làm như một cách tự nhiên", hãy xem xét một vòng lặp "trong khi". Có, bạn có thể tự lăn - nhưng điều kiện while phải nằm trong đơn nguyên vì nó cần phản ứng với tác dụng phụ của thân vòng lặp. Điều này không chỉ có nghĩa là bạn đã được cho phép gây ra tác dụng phụ trong điều kiện while, mà còn khiến bạn cảm thấy khó xử khi sử dụng vòng lặp while đó. Kết quả cuối cùng - nói chung dễ sử dụng đệ quy hơn ngay cả trong mã đơn nguyên IO - và điều đó có nghĩa là bạn phải cấu trúc mọi thứ theo một cách cụ thể.
Steve314

14

Tất cả trừ những chương trình tầm thường nhất

không thể được chứng minh đầy đủ để được chính xác với nỗ lực hợp lý. Đối với bất kỳ bằng chứng chính thức nào về tính đúng đắn, bạn cần ít nhất một thông số chính thức và thông số đó phải đầy đủ và chính xác. Điều này thường không có gì bạn có thể dễ dàng tạo ra cho hầu hết các chương trình trong thế giới thực. Ví dụ: cố gắng viết một thông số như vậy cho một cái gì đó như giao diện người dùng của trang thảo luận này và bạn hiểu ý tôi là gì.

Ở đây tôi tìm thấy một bài viết hay về chủ đề này:

http://www.encyclopedia.com/doc/1O11-programc Corrnessproof.html


Phải - đối với bất kỳ dự án lập trình nào, có một sự chuyển đổi từ một mô tả không chính thức về vấn đề sang một vấn đề chính thức (thông thường, ngày nay, dưới dạng một chương trình), và điều đó sẽ không biến mất.
David Thornley

astree.ens.fr Xem các ứng dụng công nghiệp của Astrée tại đây
zw324

@ZiyaoWei: các công cụ như vậy rất hữu ích, nhưng chúng chỉ tìm thấy một số lỗi chính thức, không nhiều hơn. Nếu một chương trình một dòng như thế printf("1")có chính xác hay không (ví dụ, vì yêu cầu là "in một số ngẫu nhiên phân phối đều từ 1 đến 6") thì không thể được quyết định bởi một bộ phân tích tĩnh như vậy.
Doc Brown

10

Vấn đề với bằng chứng chính thức là nó chỉ di chuyển vấn đề trở lại một bước.

Nói rằng một chương trình là chính xác tương đương với việc nói rằng một chương trình làm những gì nó nên làm. Làm thế nào để bạn xác định những gì chương trình nên làm? Bạn chỉ định nó. Và làm thế nào để bạn xác định những gì chương trình nên làm trong các trường hợp cạnh mà thông số kỹ thuật không bao gồm? Vâng, sau đó bạn phải làm cho thông số kỹ thuật chi tiết hơn.

Vì vậy, giả sử thông số của bạn cuối cùng trở nên đủ chi tiết để mô tả hành vi chính xác của mọi khía cạnh của toàn bộ chương trình. Bây giờ bạn cần một cách để làm cho các công cụ bằng chứng của bạn hiểu nó. Vì vậy, bạn phải dịch thông số kỹ thuật sang một số loại ngôn ngữ chính thức mà công cụ chứng minh có thể hiểu được ... này, đợi một chút!


2
Ngoài ra .. "Coi chừng các lỗi trong đoạn mã trên; tôi chỉ chứng minh là đúng, chưa thử." - Donald Knuth
Brendan

8

Xác minh chính thức đã đi một chặng đường dài, nhưng thông thường công nghiệp / công cụ được sử dụng rộng rãi tụt hậu so với nghiên cứu mới nhất. Đây là một số nỗ lực gần đây theo hướng này:

Spec # http://research.microsoft.com/en-us/projects/specsharp/ Đây là phần mở rộng của C # hỗ trợ các hợp đồng mã (điều kiện trước / sau và bất biến) và có thể sử dụng các hợp đồng này để thực hiện các loại phân tích tĩnh khác nhau .

Các dự án tương tự như vậy tồn tại cho các ngôn ngữ khác, chẳng hạn như JML cho java và Eiffel có tích hợp khá nhiều.

Đi xa hơn nữa, các dự án như slamblast có thể được sử dụng để xác minh các thuộc tính hành vi nhất định với chú thích / can thiệp lập trình viên tối thiểu, nhưng vẫn không thể xử lý toàn bộ các ngôn ngữ hiện đại (những thứ như số nguyên tràn / số học con trỏ không được mô hình hóa).

Tôi tin rằng chúng ta sẽ thấy nhiều hơn những kỹ thuật này được sử dụng trong thực tế trong tương lai. Rào cản chính là các bất biến chương trình rất khó suy ra nếu không có chú thích thủ công và các lập trình viên thường không sẵn lòng cung cấp các chú thích này vì làm như vậy quá tẻ nhạt / tốn thời gian.


4

Không trừ khi một phương pháp tự động chứng minh mã mà không có công việc phát triển rộng rãi phát sinh.


Xem xét lập luận kinh tế: có lẽ tốt hơn cho các nhà phát triển "lãng phí" thời gian với bằng chứng chính xác hơn là mất tiền vì lỗi phần mềm.
Andres F.

Tôi đồng ý với fishtoaster, trừ khi nó trở nên ít tốn nhiều tài nguyên hơn, rất nhiều phần mềm kinh doanh thông thường sẽ không có chi phí / lợi ích để hỗ trợ mức độ chính xác đó. Trong một ứng dụng LOB cho một đối tượng bị giam cầm đôi khi lợi ích kinh doanh cao nhất cho chi phí liên quan đến báo cáo lỗi là thêm một dòng vào các tài liệu có nội dung "không làm điều đó"
Bill

3

Một số công cụ phương thức chính thức (như Frama-C cho phần mềm C nhúng quan trọng) có thể được xem là (sắp xếp) cung cấp hoặc ít nhất là kiểm tra bằng chứng (chính xác) của một phần mềm nhất định. (Frama-C kiểm tra xem một chương trình tuân theo đặc điểm chính thức của nó, theo một cách nào đó, và tôn trọng các bất biến được chú thích rõ ràng trong chương trình).

Trong một số lĩnh vực, các phương pháp chính thức như vậy là có thể, ví dụ như DO-178C cho phần mềm quan trọng trong máy bay dân sự. Vì vậy, trong một số trường hợp, cách tiếp cận như vậy là có thể và hữu ích.

Tất nhiên, phát triển phần mềm ít lỗi là rất tốn kém. Nhưng phương pháp chính thức có ý nghĩa đối với một số loại phần mềm. Nếu bạn bi quan, bạn có thể nghĩ rằng lỗi được chuyển từ mã sang đặc tả chính thức của nó (có thể có một số "lỗi", vì việc chính thức hóa hành vi dự định của phần mềm là khó khăn và dễ bị lỗi).


3

Tôi vấp phải câu hỏi này và tôi nghĩ rằng liên kết này có thể thú vị:

Ứng dụng công nghiệp của Astrée

Chứng minh sự vắng mặt của RTE trong một hệ thống được Airbus sử dụng với hơn 130K dòng mã trong năm 2003 dường như không phải là xấu, và tôi tự hỏi liệu có ai nói rằng đây không phải là thế giới thực.


2

Không. Câu tục ngữ phổ biến cho điều này là, "Về lý thuyết, lý thuyết và thực hành là như nhau. Trong thực tế, không."

Một ví dụ rất đơn giản: Typose.

Trên thực tế, việc chạy mã thông qua kiểm thử đơn vị tìm thấy những thứ như vậy gần như ngay lập tức và một bộ kiểm thử gắn kết sẽ phủ nhận sự cần thiết của bất kỳ bằng chứng chính thức nào. Tất cả các trường hợp sử dụng - tốt, xấu, lỗi và các trường hợp cạnh - nên được liệt kê trong các thử nghiệm đơn vị, kết thúc bằng chứng tốt hơn là mã chính xác hơn bất kỳ bằng chứng nào tách biệt với mã.

Đặc biệt là nếu các yêu cầu thay đổi hoặc thuật toán được cập nhật để sửa lỗi - bằng chứng chính thức có nhiều khả năng sẽ hết hạn, giống như các nhận xét về mã thường nhận được.


3
Sai lầm. Không có bài kiểm tra đơn vị nào có thể bao gồm toàn bộ phạm vi của các tham số có thể. Hãy tưởng tượng "kiểm thử đơn vị" một trình biên dịch theo cách này, đảm bảo rằng không có ngữ nghĩa thay đổi vượt qua.
SK-logic

3
thử nghiệm đơn vị không phải là chén thánh ...
Ryathal

1
@Winston Ewert, có các trình biên dịch đã được xác minh (và nhiều trình biên dịch được xác minh thêm). Và phần cứng được chính thức xác minh thường xuyên hơn nhiều so với phần mềm. Xem tại đây: gallium.inria.fr/~xleroy/publi/compiler-certif.pdf
SK-logic

1
@ SK-logic, có những trình biên dịch đồ chơi đã được chứng minh là đúng cho mục đích học tập. Nhưng những gì về trình biên dịch mọi người thực sự sử dụng? Tôi nghi ngờ hầu hết các trình biên dịch được kiểm tra bằng nhiều hình thức kiểm tra tự động khác nhau và hầu như không có bằng chứng chính thức nào được thực hiện.
Winston Ewert

1
@Winston Ewert, bằng chứng chính xác là thực tế và được sử dụng rộng rãi trong cuộc sống thực. Những gì không thực tế là hầu hết các ngôn ngữ chính hiện đại. Tôi hy vọng tất cả họ sẽ chết, vì vậy giá trị của bằng chứng chính xác sẽ tăng lên trong tương lai.
SK-logic

1

Tôi nghĩ rằng các giới hạn áp đặt cho bằng chứng chính xác vì vấn đề tạm dừng có thể là rào cản lớn nhất để chứng minh tính chính xác trở thành chủ đạo.


8
Vấn đề tạm dừng nói rằng chúng tôi không thể xác định nếu bất kỳ chương trình tùy ý dừng lại. Các chương trình này có thể làm những điều kỳ lạ, như kiểm tra mọi số nguyên để xem nó có phải là số nguyên tố Mersenne không. Chúng tôi không làm điều này trong các chương trình bình thường!
Casebash

1
@Casebash, câu hỏi là liệu có một tập hợp con hữu ích của các chương trình mà vấn đề tạm dừng có thể được giải quyết hay không. Đó không phải là cách rõ ràng. Tức là chúng ta có thể hạn chế các chương trình của mình để chúng ta không thể làm những việc như kiểm tra mọi số nguyên mà không làm hỏng khả năng thực hiện các tác vụ hữu ích của mình không?
Winston Ewert

1

Nó đã được mọi người sử dụng. Mỗi khi bạn sử dụng kiểm tra loại ngôn ngữ lập trình của mình, về cơ bản bạn đang làm một bằng chứng toán học về tính đúng đắn của chương trình của bạn. Điều này đã hoạt động rất tốt - nó chỉ yêu cầu bạn chọn đúng loại cho mọi chức năng và cấu trúc dữ liệu bạn sử dụng. Loại càng chính xác, bạn sẽ càng kiểm tra tốt hơn. Các loại hiện có trong ngôn ngữ lập trình đã có các công cụ đủ mạnh để mô tả hầu hết mọi hành vi có thể. Điều này hoạt động trong mọi ngôn ngữ có sẵn. C ++ và các ngôn ngữ tĩnh chỉ thực hiện kiểm tra trong thời gian biên dịch, trong khi các ngôn ngữ động hơn như python đang thực hiện khi chương trình được chạy. Kiểm tra vẫn tồn tại trong tất cả các ngôn ngữ. (ví dụ: c ++ đã hỗ trợ kiểm tra các tác dụng phụ giống như cách haskell thực hiện,


Với một chút về tác dụng phụ trong C ++, bạn có đang đề cập đến tính chính xác của const không?
Winston Ewert

có, const + const thành viên hàm. Nếu tất cả các hàm thành viên của bạn là const, tất cả dữ liệu trong các đối tượng là không thể sửa đổi.
tp1

Chúng vẫn có thể sửa đổi nếu bạn sử dụng mutablehoặc const_cast. Tôi chắc chắn thấy kết nối bạn vẽ ở đó, nhưng hương vị của hai cách tiếp cận có vẻ khá khác nhau đối với tôi.
Winston Ewert

Chà, đó là lý do tại sao bạn cần chọn sử dụng nó - luôn có cách để đi xung quanh nó. Nhưng điều quan trọng là làm thế nào để trình biên dịch kiểm tra các vấn đề trong khu vực.
tp1
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.