Mối quan hệ giữa hợp đồng và gõ phụ thuộc


31

Tôi đã đọc một số bài viết về các loại phụ thuộc và hợp đồng lập trình. Từ phần lớn những gì tôi đã đọc, có vẻ như các hợp đồng được kiểm tra động các ràng buộc và các loại phụ thuộc được kiểm tra tĩnh.

Đã có một số giấy tờ khiến tôi nghĩ rằng có thể có hợp đồng được kiểm tra một phần tĩnh:

Với điều này, dường như có một số lượng trùng lặp đáng kể và việc phân loại hợp đồng của tôi với các loại phụ thuộc bắt đầu biến mất.

Có một cái gì đó sâu sắc hơn trong cả hai khái niệm mà tôi đang thiếu? Hay đây thực sự chỉ là những phạm trù mờ nhạt đại diện cho cùng một khái niệm cơ bản?

Câu trả lời:


26

Ở mức độ thực tế, hợp đồng là sự khẳng định. Chúng cho phép bạn kiểm tra các thuộc tính (không định lượng) của các lần thực hiện riêng lẻ của một chương trình. Ý tưởng chính ở trung tâm của việc kiểm tra hợp đồng là ý tưởng đổ lỗi - về cơ bản, bạn muốn biết ai có lỗi vì vi phạm hợp đồng. Đây có thể là một triển khai (không tính toán giá trị mà nó đã hứa) hoặc người gọi (người đã truyền một hàm loại giá trị sai).

Cái nhìn sâu sắc quan trọng là bạn có thể theo dõi việc đổ lỗi bằng cách sử dụng cùng một máy móc như các cặp trình chiếu nhúng trong cấu trúc giới hạn nghịch đảo của lý thuyết miền. Về cơ bản, bạn chuyển từ làm việc với các xác nhận sang làm việc với các cặp xác nhận, một trong số đó đổ lỗi cho bối cảnh chương trình và một trong số đó đổ lỗi cho chương trình. Sau đó, điều này cho phép bạn bao bọc các hàm bậc cao hơn bằng các hợp đồng, bởi vì bạn có thể mô hình hóa đối chiếu của không gian hàm bằng cách hoán đổi cặp xác nhận. ( Ví dụ, xem bài viết "Hoàn tác động gõ" của Nick Benton .)

Các loại phụ thuộc là các loại. Các loại xác định các quy tắc để khẳng định liệu chương trình nhất định có được chấp nhận hay không. Kết quả là, chúng không bao gồm những thứ như khái niệm đổ lỗi, vì chức năng của chúng là ngăn chặn các chương trình hành vi xấu tồn tại ở nơi đầu tiên. Không có gì để đổ lỗi vì chỉ có các chương trình được hình thành tốt thậm chí là những phát ngôn ngữ pháp. Về mặt thực tế, điều này có nghĩa là rất dễ sử dụng các loại phụ thuộc để nói về các thuộc tính của thuật ngữ với các bộ lượng hóa (ví dụ: một hàm hoạt động cho tất cả các đầu vào).

Hai quan điểm này không giống nhau, nhưng chúng có liên quan. Về cơ bản, vấn đề là với các hợp đồng, chúng tôi bắt đầu với một miền giá trị phổ quát và sử dụng các hợp đồng để cắt giảm mọi thứ. Nhưng khi chúng tôi sử dụng các loại, chúng tôi cố gắng chỉ định các miền giá trị nhỏ hơn (với thuộc tính mong muốn) ở phía trước. Vì vậy, chúng ta có thể kết nối cả hai thông qua các họ quan hệ hướng theo kiểu (tức là quan hệ logic). Ví dụ, xem "Đổ lỗi cho tất cả" gần đây của Ahmed, Findler, Siek và Wadler , hoặc "Ý nghĩa của các loại: từ ngữ nghĩa nội tại đến ngữ nghĩa bên ngoài" .


Tại sao bạn nói hợp đồng là định lượng miễn phí?
Radu GRIGore

3
Bởi vì bạn thường không thể sử dụng các bài kiểm tra để thiết lập các thuộc tính được định lượng toàn cầu của các hàm, chỉ vậy thôi.
Neel Krishnaswami

3
Trừ khi các bộ lượng hóa phạm vi trên các miền hữu hạn, trong trường hợp đó, chúng có thể được xem như là các liên kết và bất đồng lớn. Hoặc nếu bạn muốn nhận được sự ưa thích, bạn có thể kiểm tra một số loại báo cáo được định lượng nhất định, miễn là phạm vi lượng tử trên các loại có thể tìm kiếm của Martin Escardo (có thể là vô hạn).
Andrej Bauer

2
@Radu: Tôi gọi những thứ như JML & co là "logic chương trình". Các ngôn ngữ khẳng định của logic chương trình không bị giới hạn là các thuật ngữ từ ngôn ngữ của các chương trình. Điều này cho phép bạn loại trừ những thứ như xác nhận không có hiệu lực hoặc tác dụng phụ, không có cách giải thích logic hay. (Tuy nhiên, những việc như vậy rất quan trọng đối với việc kiểm tra hợp đồng - xem công việc gần đây của Pucella và Tove tại ESOP về việc sử dụng các hợp đồng cấp bách, bắt buộc để theo dõi các thuộc tính tuyến tính.)
Neel Krishnaswami

2
Đó là vì tôi đã viết sai họ của Tov. Xem "Hợp đồng có trạng thái cho các loại affine", ccs.neu.edu/home/tov/pub/affine-contuces
Neel Krishnaswami

13

Vấn đề (khá trừu tượng) mà cả hai loại và hợp đồng tấn công là "Làm thế nào để đảm bảo rằng các chương trình có các thuộc tính nhất định?". Có một sự căng thẳng cố hữu ở đây giữa việc có thể thể hiện một lớp các thuộc tính rộng hơn và có thể kiểm tra xem một chương trình có hay không một thuộc tính. Các hệ thống loại thường đảm bảo một thuộc tính rất cụ thể (chương trình không bao giờ gặp sự cố theo một số cách nhất định) và có thuật toán kiểm tra loại. Mặt khác, các hợp đồng cho phép bạn chỉ định một phạm vi rất rộng các thuộc tính (giả sử, đầu ra của chương trình này là số nguyên tố) nhưng không đi kèm với thuật toán kiểm tra.

Tuy nhiên, thực tế là không có thuật toán kiểm tra hợp đồng (luôn hoạt động) không có nghĩa là không có thuật toán kiểm tra hợp đồng gần như (có xu hướng hoạt động trong thực tế). Tôi khuyên bạn nên xem Spec #plugin Jessie của Frama-C . Cả hai đều hoạt động bằng cách thể hiện "chương trình này tuân theo hợp đồng này" như một tuyên bố trong logic thứ nhất thông qua việc tạo điều kiện xác minh , và sau đó yêu cầu một SMTngười giải quyết đi thử tìm một bằng chứng. Nếu người giải không tìm được bằng chứng, thì chương trình đó sai hoặc, tốt, người giải không tìm được bằng chứng tồn tại. (Đó là lý do tại sao đây là thuật toán kiểm tra hợp đồng "gần như") Xem, ví dụ, jstar .

Công việc của Flanagan cố gắng tận dụng những gì tốt nhất từ ​​cả hai thế giới để bạn có thể nhanh chóng kiểm tra các thuộc tính giống như loại và sau đó chuyển dạ cho phần còn lại. Tôi không thực sự quen thuộc với các loại lai, nhưng tôi nhớ tác giả nói rằng động lực của anh ấy là đưa ra một giải pháp đòi hỏi ít chú thích hơn (so với công việc trước đây của anh ấy về ESC / Java đã làm). Tuy nhiên, theo một nghĩa nào đó, có một số tích hợp lỏng lẻo giữa các loại và hợp đồng trong ESC / Java (và Spec #): khi kiểm tra hợp đồng, người giải quyết nói rằng kiểm tra kiểu đã thành công để có thể nắm bắt thông tin đó.


7

Hợp đồng có thể được kiểm tra tĩnh. Nếu bạn nhìn vào công việc cũ của Dana Xu trên ESC / Haskell , cô ấy có thể thực hiện kiểm tra hợp đồng đầy đủ vào thời gian biên dịch, chỉ dựa vào một câu tục ngữ định lý cho số học. Chấm dứt được giải quyết bằng một giới hạn độ sâu đơn giản nếu tôi nhớ chính xác:


6

Cả hợp đồng và loại cho phép bạn thể hiện các thông số kỹ thuật kiểu Hoare (điều kiện trước / sau) trên các chức năng. Cả hai có thể được kiểm tra tĩnh tại thời gian biên dịch hoặc động khi chạy.

Các loại phụ thuộc cho phép bạn mã hóa một phạm vi rất rộng các thuộc tính trong hệ thống loại, các loại thuộc tính mà các lập trình viên hợp đồng mong đợi. Điều này là do chúng có thể phụ thuộc vào các giá trị của loại. Các loại phụ thuộc có xu hướng được kiểm tra tĩnh mặc dù tôi tin rằng các bài báo bạn đã trích dẫn xem xét các phương pháp thay thế.

Cuối cùng, có rất ít sự khác biệt. Tôi nghĩ nhiều hơn là các loại phụ thuộc là một logic trong đó bạn có thể thể hiện các thông số kỹ thuật trong khi các hợp đồng là một phương pháp lập trình trong đó bạn thực hiện các đặc tả kỹ thuật.


Có một chút sai lầm khi nói rằng các chú thích kiểu Hoare có thể được kiểm tra tĩnh. Nếu logic là FO, như thường lệ, thì vấn đề chắc chắn là không thể giải quyết được. Nhưng, vâng, tôi biết bạn có nghĩa là người ta có thể cố gắng và thậm chí thành công trong nhiều tình huống.
Radu GRIGore

1
Tôi đã có ấn tượng rằng việc tạo ra bằng chứng có thể là không thể giải quyết được nhưng việc kiểm tra một bằng chứng nên được. Nhiều ngôn ngữ được gõ phụ thuộc vào người dùng để cung cấp giá trị bằng chứng của nơi cư trú của loại định lý.
Jason Reich

Bạn đúng rồi. Nhưng tôi sống trong thế giới tự động, nơi người dùng thường không được yêu cầu bằng chứng.
Radu GRIGore
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.