Xác minh chương trình chính thức trong thực tế


66

Là một kỹ sư phần mềm, tôi viết rất nhiều mã cho các sản phẩm công nghiệp. Công cụ tương đối phức tạp với các lớp, chủ đề, một số nỗ lực thiết kế, nhưng cũng có một số thỏa hiệp cho hiệu suất. Tôi làm rất nhiều thử nghiệm và tôi cảm thấy mệt mỏi khi thử nghiệm, vì vậy tôi đã quan tâm đến các công cụ chứng minh chính thức, như Coq, Isabelle ... Tôi có thể sử dụng một trong số này để chính thức chứng minh rằng mã của tôi không có lỗi và được thực hiện với nó? - nhưng mỗi lần tôi kiểm tra một trong những công cụ này, tôi bỏ đi không tin rằng chúng có thể sử dụng được cho công nghệ phần mềm hàng ngày. Bây giờ, đó chỉ có thể là tôi và tôi đang tìm kiếm con trỏ / ý kiến ​​/ ý tưởng về điều đó :-)

Cụ thể, tôi có ấn tượng rằng để làm cho một trong những công cụ này hoạt động với tôi sẽ cần một khoản đầu tư lớn để xác định đúng cách để cung cấp các đối tượng, phương thức ... của chương trình đang xem xét. Sau đó tôi tự hỏi liệu người hoạt ngôn sẽ không hết hơi với kích thước của mọi thứ mà nó sẽ phải đối phó. Hoặc có lẽ tôi sẽ phải loại bỏ các tác dụng phụ (những công cụ hoạt động đó dường như thực sự tốt với các ngôn ngữ khai báo), và tôi tự hỏi liệu điều đó có dẫn đến "mã đã được chứng minh" không thể được sử dụng bởi vì nó sẽ không nhanh hoặc đủ nhỏ Ngoài ra, tôi không có sự thay đổi ngôn ngữ mà tôi làm việc cùng, nó cần phải là Java hoặc C ++: Tôi không thể nói với sếp của mình rằng tôi sẽ viết mã bằng OXXXml kể từ bây giờ, vì đó là ngôn ngữ duy nhất trong mà tôi có thể chứng minh tính đúng đắn của mã ...

Ai đó có thể có nhiều kinh nghiệm hơn về các công cụ bằng chứng chính thức nhận xét? Một lần nữa - Tôi sẽ yêu sử dụng một công cụ Prover chính thức, tôi nghĩ rằng họ là rất lớn, nhưng tôi có ấn tượng họ đang ở trong một tháp ngà mà tôi không thể đạt được từ các mương thấp kém của Java / C ++ ... (PS: Tôi còn TÌNH YÊU Haskell, OCaml ... đừng hiểu lầm: Tôi là người hâm mộ ngôn ngữ khai báo và bằng chứng chính thức, tôi chỉ đang cố gắng để xem làm thế nào tôi có thể thực sự hữu ích cho công nghệ phần mềm)

Cập nhật: Vì điều này khá rộng, chúng ta hãy thử các câu hỏi cụ thể hơn sau đây: 1) có ví dụ nào về việc sử dụng provers để chứng minh tính đúng đắn của các chương trình Java / C ++ công nghiệp không? 2) Coq có phù hợp với nhiệm vụ đó không? 3) Nếu Coq phù hợp, tôi có nên viết chương trình trong Coq trước không, sau đó tạo C ++ / Java từ Coq? 4) Cách tiếp cận này có thể xử lý tối ưu hóa luồng và hiệu suất?


3
Tôi nhận được và đánh giá cao vấn đề của bạn, nhưng tôi không hiểu câu hỏi này là gì (như một bài đăng SE). Thảo luận? Kinh nghiệm? Không thích hợp cho SE. "Tôi có thể làm gì?" giai điệu làm cho tôi cảm thấy đây là một câu hỏi quá rộng.
Raphael

3
Tôi hiểu ... Tôi đồng ý câu hỏi này không được xây dựng rõ ràng. Vì vậy, giả sử: 1) có ví dụ nào về việc sử dụng provers để chứng minh tính đúng đắn của các chương trình Java / C ++ công nghiệp không? 2) Coq có phù hợp với nhiệm vụ đó không? 3) Nếu Coq phù hợp, tôi có nên viết chương trình trong Coq trước không, sau đó Coq có tạo C ++ / Java từ đó không? 4) Cách tiếp cận này có thể đối phó với tối ưu hóa luồng và hiệu suất?
Frank

2
Vì vậy, đó là bốn câu hỏi. 1) có lẽ tốt hơn về Kỹ thuật phần mềm vì bạn không có khả năng gặp phải (nhiều) chuyên gia trong ngành ở đây. 2) thị hiếu hơi chủ quan, nhưng chúng ta có thể có những người ở đây có thể đưa ra một quan điểm khách quan. 3) là, theo như tôi có thể nói, hoàn toàn chủ quan. 4) Là một câu hỏi hay cho trang web này. Tóm lại: vui lòng phân tách các câu hỏi của bạn, trước tiên hãy đến Kỹ thuật phần mềm và suy nghĩ kỹ xem bạn có thể mong đợi câu trả lời khách quan (!) Tại đây (!) Trước khi đăng 2) không.
Raphael

10
Bạn đang mô tả giấc mơ xác minh chính thức, nhưng chúng ta ở rất xa đó. AFAIK, xác minh chương trình là một nhiệm vụ không thường xuyên và chỉ áp dụng cho các chương trình rất đơn giản. Điều đó nói rằng, tôi nghĩ rằng câu hỏi này được đặt ra cho trang web và tôi sẽ đánh giá cao ai đó trong khu vực thừa nhận giới hạn của lĩnh vực của họ, giải thích các hạn chế và hạn chế (có lẽ bằng cách liên kết với một số khảo sát ).
Yuval Filmus

9
Vấn đề với việc xác minh các chương trình C ++ là C ++ không phải là một ngôn ngữ được xác định rõ. Tôi không nghĩ có thể xác minh quy mô lớn cho đến khi nhiều phần của hệ thống phần mềm (HĐH, thư viện, ngôn ngữ lập trình) thực sự được thiết kế lại để hỗ trợ xác minh. Như đã biết, bạn không thể đổ 200000 dòng mã vào ai đó và nói "xác minh!". Bạn cần xác minh và viết mã cùng nhau, và bạn cần điều chỉnh thói quen lập trình của mình với thực tế là bạn cũng đang xác minh.
Andrej Bauer

Câu trả lời:


35

Tôi sẽ cố gắng đưa ra một câu trả lời ngắn gọn cho một số câu hỏi của bạn. Xin lưu ý rằng đây không hoàn toàn là lĩnh vực nghiên cứu của tôi, vì vậy một số thông tin của tôi có thể bị lỗi thời / không chính xác.

  1. Có nhiều công cụ được thiết kế đặc biệt để chính thức chứng minh các thuộc tính của Java và C ++.

    Tuy nhiên tôi cần thực hiện một lạc đề nhỏ ở đây: việc chứng minh tính đúng đắn của một chương trình có nghĩa là gì? Trình kiểm tra kiểu Java chứng minh một thuộc tính chính thức của chương trình Java, cụ thể là các lỗi nhất định, như thêm a floatvà an int, không bao giờ có thể xảy ra! Tôi tưởng tượng bạn quan tâm đến các thuộc tính mạnh hơn nhiều, cụ thể là chương trình của bạn không bao giờ có thể rơi vào trạng thái không mong muốn hoặc đầu ra của một hàm nhất định tuân theo một đặc tả toán học nhất định. Nói tóm lại, có một độ dốc lớn về việc "chứng minh chương trình chính xác" có thể có nghĩa là gì, từ các thuộc tính bảo mật đơn giản đến bằng chứng đầy đủ rằng chương trình đáp ứng một đặc tả chi tiết.

    Bây giờ tôi sẽ giả định rằng bạn quan tâm đến việc chứng minh các thuộc tính mạnh mẽ về các chương trình của bạn. Nếu bạn quan tâm đến các thuộc tính bảo mật (chương trình của bạn không thể đạt đến một trạng thái nhất định), thì nói chung có vẻ như cách tiếp cận tốt nhất là kiểm tra mô hình . Tuy nhiên, nếu bạn muốn chỉ định đầy đủ hành vi của một chương trình Java, thì cách tốt nhất của bạn là sử dụng ngôn ngữ đặc tả cho ngôn ngữ đó, ví dụ như JML . Có những ngôn ngữ như vậy để chỉ định hành vi của các chương trình C, ví dụ ACSL , nhưng tôi không biết về C ++.

  2. Khi bạn có thông số kỹ thuật của mình, bạn cần chứng minh rằng chương trình phù hợp với đặc điểm kỹ thuật đó.

    Đối với điều này, bạn cần một công cụ có hiểu biết chính thức về cả đặc tả và ngữ nghĩa hoạt động của ngôn ngữ của bạn (Java hoặc C ++) để diễn đạt định lý đầy đủ , cụ thể là việc thực thi chương trình tôn trọng đặc tả.

    Công cụ này cũng sẽ cho phép bạn xây dựng hoặc tạo ra bằng chứng của định lý đó. Bây giờ cả hai nhiệm vụ này (chỉ định và chứng minh) đều khá khó khăn, vì vậy chúng thường được tách thành hai:

    • Một công cụ phân tích mã, đặc tả và tạo định lý đầy đủ. Như Frank đã đề cập, Krakatoa là một ví dụ về một công cụ như vậy.

    • Một công cụ chứng minh (các) định lý, tự động hoặc tương tác. Coq tương tác với Krakatoa theo cách này, và có một số công cụ tự động mạnh mẽ như Z3 cũng có thể được sử dụng.

    Một điểm (nhỏ): có một số định lý quá khó để được chứng minh bằng các phương pháp tự động, và các trình xử lý định lý tự động được biết là thỉnh thoảng có các lỗi âm thanh khiến chúng không đáng tin cậy. Đây là một lĩnh vực mà Coq tỏa sáng so sánh (nhưng nó không tự động!).

  3. Nếu bạn muốn tạo mã Ocaml, sau đó chắc chắn viết bằng Coq (Gallina) trước, sau đó giải nén mã. Tuy nhiên, Coq rất tệ trong việc tạo C ++ hoặc Java, nếu có thể.

  4. Các công cụ trên có thể xử lý các vấn đề luồng và hiệu suất? Có lẽ là không, các mối quan tâm về hiệu năng và luồng được xử lý tốt nhất bằng các công cụ được thiết kế đặc biệt, vì chúng là những vấn đề đặc biệt khó khăn. Tôi không chắc chắn tôi có bất kỳ công cụ nào để giới thiệu ở đây, mặc dù dự án PolyNI của Martin Hofmann có vẻ thú vị.

Tóm lại: xác minh chính thức các chương trình Java và C ++ "thế giới thực" là một lĩnh vực rộng lớn và được phát triển tốt và Coq phù hợp với các phần của nhiệm vụ đó. Bạn có thể tìm thấy một cái nhìn tổng quan cấp cao ở đây chẳng hạn.


Cảm ơn cho bài viết này và các tài liệu tham khảo bạn đã thêm. IMHO, mục tiêu của các kỹ sư phần mềm là có thể nhanh chóng phát hành các hệ thống sẽ luôn cung cấp kết quả chính xác, 2) không bao giờ thất bại. Tôi có thể thấy một vấn đề hồi quy ở đây, nơi bạn có thể muốn chứng minh rằng chính đặc tả đó là "không có lỗi" :-) giống như cố gắng định nghĩa "mệnh đề thực sự của ngôn ngữ" với ngôn ngữ meta, sau đó cần một meta khác ngôn ngữ cho điều đó, sau đó một ngôn ngữ khác ...
Frank

6
Vấn đề là những gì người dùng "muốn" thường không được thể hiện bằng ngôn ngữ chính thức! Nhìn chung không có câu trả lời chính thức cho câu hỏi: "thông số kỹ thuật chính thức này có phù hợp với ý tưởng không chính thức của tôi không?". Có thể kiểm tra một đặc tả chính thức và chứng minh rằng nó có các tính chất toán học nhất định, nhưng cuối cùng bạn cần liên hệ toán học với thế giới thực, đó là một quá trình không chính thức.
cody

Có tất nhiên - tôi luôn nhận ra các phương thức chính thức chỉ có thể bắt đầu từ một điểm được xác định rõ. Nếu đặc điểm kỹ thuật đó phù hợp hoặc không phù hợp với nhu cầu có ý thức / vô thức / chưa được khám phá của người dùng thực tế là một vấn đề khác, không thể giải quyết bằng các phương pháp chính thức (nhưng chắc chắn là vấn đề đối với các kỹ sư).
Frank

Một định lý là theo định nghĩa một đề xuất đã được chứng minh. Vì vậy, có lẽ bạn không có nghĩa là "chứng minh định lý".
nbro

@nbro Wikipedia dường như đồng ý với bạn. Mathworld, tuy nhiên, định nghĩa một định lý là một mệnh đề " có thể được chứng minh là đúng bởi các phép toán được chấp nhận". Trong trường hợp này, việc đưa ra bằng chứng về các định lý không chỉ có thể, mà còn cần thiết để biện minh cho việc gọi chúng như vậy! :) (tất nhiên đây là một phản công)
cody

15

Tôi muốn đề cập đến ba ứng dụng đáng chú ý của các phương pháp chính thức / công cụ xác minh chính thức trong các hệ thống thực tế công nghiệp hoặc không tầm thường. Lưu ý rằng tôi có ít kinh nghiệm về chủ đề này và tôi chỉ học chúng từ việc đọc các bài báo.

  1. Công cụ mã nguồn mở Java Pathfinder (viết tắt là JPF) do NASA phát hành năm 2005 là một hệ thống để xác minh các chương trình mã byte Java thực thi (xem Java Pathfinder @ wiki ). Nó đã được sử dụng để phát hiện sự không nhất quán trong phần mềm điều hành cho K9 Rover tại NASA Ames.

  2. Bài viết này: Sử dụng Kiểm tra mô hình để tìm lỗi hệ thống tệp nghiêm trọng @ OSDI'04 cho thấy cách sử dụng kiểm tra mô hình để tìm lỗi nghiêm trọng trong hệ thống tệp. Một hệ thống có tên FiSC được áp dụng cho ba hệ thống tệp được sử dụng rộng rãi, được thử nghiệm nhiều: ext3, JFS và ReiserFS và 32 lỗi nghiêm trọng được tìm thấy. Nó đã giành giải thưởng giấy tốt nhất.

  3. Bài viết này: Cách dịch vụ web của Amazon sử dụng các phương thức chính thức @ CACM'15 mô tả cách AWS áp dụng các phương thức chính thức cho các sản phẩm của mình như S3, DynamoDB, EBS và trình quản lý khóa phân tán nội bộ. Nó tập trung vào công cụ TLA + của Lamport . Nhân tiện, Lamport đã sử dụng mạnh mẽ hộp công cụ TLA của riêng mình. Ông thường đưa ra một xác minh chính thức (khá đầy đủ) trong TLA về các thuật toán / định lý do chính ông (cũng như các đồng tác giả) đề xuất trong các phụ lục của bài báo.


4

Một đặc tả chính thức của một chương trình là (ít nhiều) một chương trình được viết bằng ngôn ngữ lập trình khác. Kết quả là, đặc điểm kỹ thuật chắc chắn sẽ bao gồm các lỗi riêng của nó.

Ưu điểm của xác minh chính thức là, vì chương trình và đặc tả là hai triển khai riêng biệt, các lỗi của chúng sẽ khác nhau. Nhưng không phải lúc nào: một nguồn lỗi phổ biến, các trường hợp bị bỏ qua, thường sẽ khớp. Do đó, xác minh chính thức không phải là thuốc chữa bách bệnh: nó vẫn có thể bỏ lỡ một số lỗi không hề nhỏ.

Một nhược điểm của xác minh chính thức là nó có thể áp dụng chi phí gấp đôi chi phí thực hiện, có thể nhiều hơn (bạn cần một chuyên gia về đặc tả chính thức và bạn cần sử dụng các công cụ thử nghiệm ít nhiều đi kèm với nó; sẽ không rẻ ).

Tôi đoán việc thiết lập các trường hợp thử nghiệm và giàn giáo để chạy chúng tự động sẽ giúp bạn sử dụng thời gian tốt hơn.


Các lợi thế của xác minh chính thức là .... Một thứ hai bất lợi của chính thức xác minh là ... Đây là khó hiểu.
hengxin

Tôi nghĩ rằng sự không phù hợp giữa đặc tả và nhiệm vụ không chính thức là một vấn đề phân tích yêu cầu phần mềm không phải là vấn đề lập trình.
Kaveh

3

Hiện tại có thể xác minh chính thức cho các chương trình viết một tập hợp con C ++ được thiết kế cho các hệ thống nhúng quan trọng an toàn. Xem http://eschertech.com/ersky/CanCPlusPlusBeMadeAsSafeAsSpark.ppt để biết bản trình bày ngắn và http://eschertech.com/ con / CatluslusPlusBeMadeAsSafeAsSpark.pdf để biết toàn bộ bài viết.


5
Cảm ơn các liên kết. Ít nhất một tổng quan ngắn gọn về nội dung của chúng sẽ hữu ích, để bảo vệ chống thối liên kết, đặc biệt vì các liên kết của bạn đến một trang web của công ty: những liên kết này được tổ chức lại theo định kỳ, giết chết tất cả các liên kết vào trang web.
David Richerby

2

Bạn hỏi một vài câu hỏi khác nhau. Tôi đồng ý rằng có vẻ như các phương pháp xác minh chính thức cho các ứng dụng công nghiệp / thương mại không quá phổ biến. tuy nhiên, người ta nên nhận ra rằng rất nhiều nguyên tắc "xác minh chính thức" được tích hợp vào trình biên dịch để xác định tính chính xác của chương trình! Vì vậy, theo một cách nào đó, nếu bạn sử dụng một trình biên dịch hiện đại, bạn đang sử dụng nhiều công nghệ tiên tiến nhất trong xác minh chính thức.

Bạn nói "Tôi mệt mỏi khi thử nghiệm" nhưng xác minh chính thức không thực sự thay thế cho thử nghiệm. theo cách nó là một biến thể của thử nghiệm.

Bạn đề cập đến Java. có nhiều phương thức xác minh chính thức nâng cao được tích hợp trong chương trình xác minh java có tên FindBugs mà thực sự có thể chạy trên các cơ sở mã lớn. Lưu ý rằng nó sẽ bật lên cả "dương tính giả và âm tính giả" và kết quả cần được xem xét / phân tích bởi một nhà phát triển con người. Nhưng lưu ý ngay cả khi nó không bật các khiếm khuyết chức năng thực sự, nó thường bật lên các "antipotype" nên tránh trong mã.

Bạn không đề cập nhiều đến ứng dụng cụ thể của bạn ngoài "công nghiệp". Xác minh chính thức trong thực tế có xu hướng phụ thuộc vào ứng dụng cụ thể.

Các kỹ thuật xác minh chính thức dường như được sử dụng rộng rãi trong EE để chứng minh tính chính xác của mạch, ví dụ như trong thiết kế bộ vi xử lý.

Dưới đây là một ví dụ về khảo sát các công cụ xác minh chính thức trong lĩnh vực EE của Lars Philipson .


2
Thật sai lầm khi nói rằng "rất nhiều nguyên tắc" xác minh chính thức "được tích hợp vào trình biên dịch để xác định tính chính xác của chương trình". Những gì bạn đề cập đến là kiểm tra kiểu tĩnh mà một số trình biên dịch thực hiện, nhưng các thuộc tính được xác minh theo cách đó khá đơn giản, ví dụ như tránh thêm một số và một chuỗi. Điều này rất hữu ích, nhưng khác xa với những gì thường được đánh giá thấp bởi "xác minh chính thức".
Martin Berger

2
đã không đề cập đến việc kiểm tra kiểu tĩnh một cách cụ thể, mặc dù đó là một ví dụ đơn giản / phổ biến. Các kỹ thuật tối ưu hóa trình biên dịch imho, phổ biến và tiên tiến, gần giống với các nguyên tắc xác minh chính thức, bởi vì chúng liên quan đến các kỹ thuật nâng cao để xác định / hiển thị sự tương đương của các biến thể chương trình được tối ưu hóa. Vì vậy, có vẻ như điều quan trọng là phải tránh vấn đề "di chuyển mục tiêu" ở đây và không cho rằng đó chỉ là do trình biên dịch thực hiện hoặc được tích hợp vào trình biên dịch, không phải là xác minh chính thức.
vzn

2
đồng ý đây không phải là một sự hiểu biết chung. các kỹ thuật tối ưu hóa đại khái đang tạo ra một mô hình hành vi chương trình, ví dụ như một vòng lặp hoặc chương trình con, và tối ưu hóa mô hình đó, và sau đó tạo mã mới tương đương với chứng minh. vì vậy một số tối ưu hóa này khá phức tạp trong việc sắp xếp lại mã & với tôi chúng sử dụng các nguyên tắc xác minh chính thức. Dường như có nhiều ví dụ khác về các phương thức xác minh chính thức trong trình biên dịch ... câu hỏi ban đầu đã hỏi nhiều câu hỏi khác nhau như nhiều người đã lưu ý, tôi không cố gắng trả lời tất cả các câu hỏi có trong đó.
vzn

2
bằng cách này, dường như có một số nguyên tắc xác minh chính thức cũng được sử dụng trong JRE, công cụ thời gian chạy java, ví dụ: tối ưu hóa động, v.v ...
vzn

3
xy

1

Có lẽ, một trình kiểm tra mô hình có thể hữu ích.

http://alloytools.org/documentation.html Alloy là công cụ kiểm tra mô hình.

Một bài thuyết trình hay giải thích khái niệm kiểm tra mô hình bằng Alloy: https://www.youtube.com/watch?v=FvNRlE4E9QQ

Trong cùng một nhóm các công cụ có 'thử nghiệm dựa trên thuộc tính', tất cả chúng đều cố gắng tìm một ví dụ ngược cho mô hình đặc tả cụ thể của phần mềm của bạn.

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.