Tại sao viết ra bằng chứng toán học chống lỗi nhiều hơn viết mã máy tính?


190

Tôi đã nhận thấy rằng tôi thấy việc viết ra các bằng chứng toán học dễ dàng hơn rất nhiều mà không mắc lỗi nào, hơn là viết ra một chương trình máy tính không có lỗi.

Có vẻ như đây là một cái gì đó phổ biến hơn là kinh nghiệm của tôi. Hầu hết mọi người tạo ra lỗi phần mềm mọi lúc trong lập trình của họ và họ có trình biên dịch để cho họ biết lỗi là gì mọi lúc. Tôi chưa bao giờ nghe nói về một người đã viết một chương trình máy tính lớn mà không có lỗi trong một lần, và hoàn toàn tin tưởng rằng nó sẽ không có lỗi. (Trong thực tế, hầu như không có chương trình nào là không có lỗi, thậm chí nhiều chương trình được sửa lỗi cao).

Tuy nhiên, mọi người có thể viết toàn bộ giấy tờ hoặc sách chứng minh toán học mà không cần bất kỳ trình biên dịch nào cung cấp cho họ thông tin phản hồi rằng họ đã mắc lỗi và đôi khi không nhận được phản hồi từ người khác.

Hãy để tôi được rõ ràng. Điều này không có nghĩa là mọi người không mắc lỗi trong các bằng chứng toán học, nhưng đối với các nhà toán học có kinh nghiệm nhẹ, các lỗi thường không có vấn đề gì và có thể được giải quyết mà không cần sự trợ giúp của một "nhà tiên tri bên ngoài" như trình biên dịch chỉ vào sai lầm.

Trong thực tế, nếu đây không phải là trường hợp, thì toán học hiếm khi có thể xảy ra với tôi.

Vì vậy, điều này khiến tôi đặt ra câu hỏi: Có gì khác biệt khi viết bằng chứng toán học không có lỗi và viết mã máy tính không có lỗi khiến cho cái trước trở nên dễ điều khiển hơn cái sau?

Người ta có thể nói rằng đó chỉ đơn giản là việc mọi người có "lời tiên tri bên ngoài" của trình biên dịch chỉ cho họ những sai lầm khiến các lập trình viên lười biếng, ngăn họ làm những gì cần thiết để viết mã một cách chặt chẽ. Quan điểm này có nghĩa là nếu họ không có trình biên dịch, họ sẽ có thể không có lỗi như các nhà toán học.

Bạn có thể thấy điều này thuyết phục, nhưng dựa trên kinh nghiệm lập trình của tôi và viết ra các bằng chứng toán học, có vẻ như trực giác với tôi rằng đây thực sự không phải là lời giải thích. Dường như có một cái gì đó khác biệt hơn về hai nỗ lực.

Suy nghĩ ban đầu của tôi là, điều có thể là sự khác biệt, là đối với một nhà toán học, một bằng chứng chính xác chỉ yêu cầu mỗi bước logic duy nhất là chính xác. Nếu mỗi bước là đúng, toàn bộ bằng chứng là chính xác. Mặt khác, để một chương trình không có lỗi, không chỉ mỗi dòng mã phải chính xác, mà mối quan hệ của nó với mọi dòng mã khác trong chương trình cũng phải hoạt động tốt.

Nói cách khác, nếu bước trong một bằng chứng là chính xác, thì việc mắc lỗi ở bước sẽ không làm hỏng bước bao giờ. Nhưng nếu một dòng mã được viết chính xác, thì việc mắc lỗi trong dòng sẽ ảnh hưởng đến hoạt động của dòng , do đó, bất cứ khi nào chúng ta viết dòng chúng ta phải tính đến mối quan hệ của nó với tất cả các dòng khác. Chúng ta có thể sử dụng đóng gói và tất cả những thứ đó để hạn chế điều này, nhưng nó không thể được loại bỏ hoàn toàn.Y X X Y X XXYXXYXX

Điều này có nghĩa là quy trình kiểm tra lỗi trong một bằng chứng toán học về cơ bản là tuyến tính theo số bước chứng minh, nhưng quy trình kiểm tra lỗi trong mã máy tính về cơ bản là theo cấp số nhân của số dòng mã.

Bạn nghĩ sao?

Lưu ý: Câu hỏi này có số lượng lớn câu trả lời khám phá nhiều sự kiện và quan điểm khác nhau. Trước khi bạn trả lời, xin vui lòng đọc tất cả chúng và chỉ trả lời nếu bạn có một cái gì đó mới để thêm. Câu trả lời dư thừa hoặc câu trả lời không sao lưu ý kiến ​​với sự thật, có thể bị xóa.


3
Bạn có biết các bằng chứng về tính đúng đắn cho các chương trình, cả trên giấy và cơ giới hóa trong các định lý định lý không? Cả hai đều tồn tại và mâu thuẫn với bản cập nhật của bạn. đúng là lập trình như thường được dạy ít có liên quan đến lập trình với bằng chứng chính xác.
Blaisorblade

76
Nhắc nhở tôi về một trích dẫn Knuth, tôi nghĩ rằng "Hãy coi chừng đoạn mã trên! Tôi chỉ chứng minh nó đúng, tôi chưa bao giờ kiểm tra nó"
Hagen von Eitzen

Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Gilles

7
Tìm cho tôi một bằng chứng toán học viết tay dài 100 triệu dòng và không có "lỗi", và tôi sẽ cung cấp cho bạn mọi thứ tôi sở hữu.
Thưởng thức

Các chương trình chức năng có thể dễ viết hơn nhiều so với bằng chứng, tuy nhiên, ngay khi trạng thái xuất hiện ... khó khăn bùng nổ ...
aoeu256

Câu trả lời:


226

Hãy để tôi đưa ra một lý do và một quan niệm sai lầm như một câu trả lời cho câu hỏi của bạn.

Các nguyên nhân chính đó là dễ dàng hơn để viết (dường như) đúng bằng chứng toán học là chúng được viết ở một mức độ rất cao. Giả sử bạn có thể viết một chương trình như thế này:

function MaximumWindow(A, n, w):
    using a sliding window, calculate (in O(n)) the sums of all length-w windows
    return the maximum sum (be smart and use only O(1) memory)

Sẽ khó khăn hơn nhiều khi lập trình theo cách này, vì đặc điểm kỹ thuật của chương trình ngắn gọn hơn nhiều so với việc thực hiện . Thật vậy, mọi lập trình viên cố gắng chuyển đổi mã giả thành mã, đặc biệt là mã hiệu quả, gặp phải khoảng cách lớn giữa ý tưởng về thuật toán và chi tiết triển khai của nó . Bằng chứng toán học tập trung nhiều hơn vào các ý tưởng và ít hơn vào chi tiết.

Bản sao thực sự của mã cho bằng chứng toán học là bằng chứng hỗ trợ máy tính . Chúng khó phát triển hơn nhiều so với các bằng chứng văn bản thông thường và người ta thường phát hiện ra nhiều góc khuất khác nhau "rõ ràng" đối với người đọc (những người thường không chú ý đến chúng), nhưng không rõ ràng đối với máy tính. Ngoài ra, vì hiện tại máy tính chỉ có thể lấp đầy những khoảng trống tương đối nhỏ, nên các bằng chứng phải được xây dựng đến mức mà một người đọc chúng sẽ bỏ lỡ khu rừng để trồng cây.

Một quan niệm sai lầm quan trọng là bằng chứng toán học thường đúng. Trong thực tế, điều này có lẽ là khá lạc quan. Rất khó để viết bằng chứng phức tạp mà không có lỗi, và giấy tờ thường có lỗi. Có lẽ trường hợp nổi tiếng nhất gần đây là nỗ lực Wiles' đầu tiên tại (một trường hợp đặc biệt của) định lý mô đun (trong đó hàm ý định lý cuối cùng của Fermat), và khoảng cách khác nhau trong việc phân loại các nhóm đơn giản hữu hạn, trong đó có một số 1000 trang trên nhóm quasithin đó là được viết 20 năm sau khi phân loại được cho là đã hoàn thành.

Một sai lầm trong một bài báo của Voevodsky đã khiến anh nghi ngờ bằng chứng bằng văn bản đến nỗi anh bắt đầu phát triển lý thuyết kiểu đồng luân , một khung logic hữu ích để phát triển lý thuyết đồng luân chính thức, và từ đó sử dụng máy tính để xác minh tất cả công việc tiếp theo của anh (ít nhất là theo ý của anh nhận vào). Mặc dù đây là một vị trí cực đoan (và hiện tại, không thực tế), nhưng vẫn là trường hợp khi sử dụng một kết quả, người ta phải đi qua bằng chứng và kiểm tra xem nó có đúng không. Trong khu vực của tôi có một vài bài báo được biết là sai nhưng chưa bao giờ được rút lại, tình trạng của họ được chuyển từ miệng sang tai giữa các chuyên gia.


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
DW

1
Có thể trong tương lai, trợ lý bằng chứng sẽ được sử dụng để kiểm tra cả mã và bằng chứng của bạn? Có lẽ đã đến lúc tìm hiểu bạn một Agda ? (xin lỗi ...)
Alex Vong

3
@AlexVong Một vấn đề với điều đó là việc viết một đặc tả chính thức cho mã không tầm thường (để bạn có thể xác minh rằng mã thực sự đáp ứng đặc tả) là không thể. Ví dụ: bạn có thể tưởng tượng một đặc tả chính thức cho trình duyệt sẽ phức tạp như thế nào (bao gồm tất cả các tương tác của người dùng, tất cả các định dạng tệp và giao thức được hỗ trợ, v.v.) không?
Svick

2
@svick Bạn nói đúng, đối với sự tương tác của người dùng, đôi khi thậm chí còn không rõ hành vi nào là đúng. Vì vậy, thay vào đó chúng ta nên tập trung vào một cái gì đó với một đặc điểm kỹ thuật chính thức (ví dụ bằng chứng, trình biên dịch).
Alex Vong

1
Thật. Đó cũng có thể là một lời giải thích cho lý do tại sao nhiều người sẽ thấy việc viết mã bằng các ngôn ngữ cấp thấp trở nên tẻ nhạt và ít thú vị hơn nhiều so với mã hóa bằng các ngôn ngữ trừu tượng, cấp cao. Mặc dù điều đó cũng có thể khác nhau theo từng người, dĩ nhiên (Một số người thậm chí có thể thích xây dựng các mạch phần cứng / điện tử ở mức độ thấp hơn nhiều so với việc viết phần mềm chạy trên chúng? Ngoài ra, mã cấp thấp hơn vẫn có thể thay thế được trong nhiều trường hợp và viết tốt có thể là một kỹ năng khan hiếm / kỳ công xứng đáng để tự khen ngợi).
xji

77

(Tôi có thể mạo hiểm một vài downvote ở đây, vì tôi không có thời gian / sở thích để đưa ra câu trả lời thích hợp này, nhưng tôi thấy văn bản được trích dẫn (và phần còn lại của bài viết được trích dẫn) bên dưới khá sâu sắc, cũng xem xét chúng được viết bởi một nhà toán học nổi tiếng. Có lẽ tôi có thể cải thiện câu trả lời sau.)

Ý tưởng, mà tôi cho rằng không đặc biệt khác biệt với câu trả lời hiện có, đó là một "bằng chứng" hoặc lập luận truyền đạt đến một cộng đồng toán học, trong đó mục đích là để thuyết phục họ rằng các chi tiết (tẻ nhạt) có thể được điền vào, theo nguyên tắc, để đạt được một bằng chứng chính thức được chỉ định đầy đủ - mà không thường xuyên làm như vậy. Một ví dụ quan trọng của điều này là bạn có thể sử dụng các định lý hiện có bằng cách chỉ rõ chúng, nhưng việc sử dụng lại mã nói chung khó khăn hơn nhiều. Cũng xem xét các "lỗi" nhỏ, có thể hoàn toàn khiến một đoạn mã trở nên vô dụng (ví dụ: SEGFAULTs) nhưng có thể để lại một đối số toán học nguyên vẹn (nghĩa là, nếu lỗi có thể được chứa mà không bị sụp đổ đối số).

Tiêu chuẩn về tính đúng đắn và đầy đủ cần thiết để làm cho một chương trình máy tính hoạt động hoàn toàn là một số đơn đặt hàng có cường độ cao hơn tiêu chuẩn chứng minh hợp lệ của cộng đồng toán học. Tuy nhiên, các chương trình máy tính lớn, ngay cả khi chúng đã được viết rất cẩn thận và được kiểm tra rất cẩn thận, dường như luôn có lỗi. [...] Toán học khi chúng tôi thực hành nó hoàn chỉnh và chính xác hơn nhiều so với các ngành khoa học khác, nhưng nó hoàn toàn chính thức và ít chính xác hơn cho nội dung của nó so với các chương trình máy tính. Sự khác biệt không chỉ xảy ra với số lượng nỗ lực: loại nỗ lực khác nhau về chất. Trong các chương trình máy tính lớn, phải dành một phần lớn nỗ lực cho vô số vấn đề tương thích: đảm bảo rằng tất cả các định nghĩa đều nhất quán, phát triển "tốt" cấu trúc dữ liệu có tính tổng quát hữu ích nhưng không cồng kềnh, quyết định tính tổng quát "đúng" cho các chức năng, v.v ... Tỷ lệ năng lượng dành cho phần làm việc của một chương trình lớn, như được phân biệt với phần kế toán, là nhỏ đáng ngạc nhiên. Do các vấn đề tương thích gần như không thể tránh khỏi leo thang vì các định nghĩa "đúng" thay đổi khi tính tổng quát và chức năng được thêm vào, các chương trình máy tính thường cần phải được viết lại thường xuyên, thường là từ đầu.

VỀ THỰC TRẠNG VÀ TIẾN ĐỘ TRONG TOÁN HỌC (trang 9-10), bởi WILLIAM P. THURoston https://arxiv.org/pdf/math/9404236.pdf


3
Điểm về "tái sử dụng mã" là khá apropos. Dịch một bằng chứng dài từ tiếng Nga sang tiếng Anh mất khá nhiều thao tác đánh máy ; nhưng việc dịch một chương trình máy tính lớn từ, giả sử, C ++ sang Java, cần khá nhiều suy nghĩ . Ngoài ra, việc hồi sinh một bằng chứng 3000 năm trong tiếng Hy Lạp cổ đại cũng dễ dàng như vậy; hồi sinh một chương trình 30 năm trong PL / 1 chỉ là khó, hoặc khó hơn.
Quuxplusone

2
Ví dụ Hy Lạp cổ đại cũng khiến tôi nhận ra: lập trình viên máy tính sử dụng một tấn của tiếng lóng địa phương và colloquialisms, chẳng hạn như (void*)1open('/dev/null'), mà thậm chí có thể không di động giữa nền văn hóa khác nhau, hãy để một mình thể dịch sang ngôn ngữ đích. (Người đọc chỉ cần tìm hiểu ngữ nghĩa gần đúng của họ bằng kinh nghiệm lâu năm.) Tôi nghĩ rằng bằng chứng toán học chứa ít loại "tiếng lóng" này. Nếu một bằng chứng sử dụng một từ, ý nghĩa phổ quát thực sự của nó được cho là do người đọc suy luận bằng cách nào đó. Các chương trình máy tính thậm chí không ý nghĩa phổ quát!
Quuxplusone

1
+1, vì là một nhà xây dựng , giả định tràn lan của một khác biệt với một giá trị lớn tùy ý khiến tôi phát điên. Điều này tăng từ ngụy biện ở cấp độ giá trị sang ngụy biện logic khi các nhà toán học bắt đầu nói về chuỗi vô hạn và sau đó đưa ra các đối số dựa trên chuỗi đó, gây ra lỗi ngang bằng với sai lầm ẩn . 000
Nat

@Nat bạn có thể giải thích? Tôi không hiểu
Gregory Magarshak

@GregoryMagarshak Câu trả lời này đã chứng minh một trường hợp trong đó giả định của giá trị vô cực trong xây dựng hàng loạt dẫn đến một sai lầm, mà tôi đã được mô tả như là như này hidden- sai lầm00 (các " trá hình " phiên bản thấp hơn trong Wikipedia phần). Một nhà toán học cổ điển có thể nói rằng sai lầm đã cho rằng một chuỗi vô hạn hội tụ, mặc dù một nhà xây dựng sẽ mô tả ngụy biện là một giả định không đủ tiêu chuẩn của vô cực.
Nat

55

Cho phép tôi bắt đầu bằng cách trích dẫn EW Dijkstra:

"Lập trình là một trong những nhánh khó nhất của toán học ứng dụng; các nhà toán học nghèo hơn vẫn tốt hơn là các nhà toán học thuần túy." (từ EWD498)

Mặc dù ý nghĩa của Dijkstra với 'lập trình' khác khá nhiều so với cách sử dụng hiện tại, vẫn có một số giá trị trong trích dẫn này. Các câu trả lời khác đã đề cập rằng mức độ trừu tượng trong toán học được phép cao hơn rất nhiều so với lập trình, có nghĩa là chúng ta có thể bỏ qua một số phần khó khăn nếu chúng ta muốn làm như vậy.

Tuy nhiên, tôi tin rằng đây chỉ là hệ quả của sự khác biệt cơ bản hơn giữa bằng chứng và chương trình máy tính, đó là mục đích của họ .

Mục đích chính của một bằng chứng toán học là, trong số những người khác, để thuyết phục bản thân rằng một tuyên bố toán học là chính xác và, có lẽ thậm chí còn quan trọng hơn, đạt được sự hiểu biết . Do đó, bạn có thể chọn chỉ làm việc trong thế giới toán học, nơi mọi thứ được tạo ra sao cho có thể đạt được sự hiểu biết bằng thiết kế (mặc dù một số học sinh cầu xin khác biệt ...) Đây chính xác là ý của Dijkstra với "nhà toán học thuần túy", những người (hầu như) chỉ quan tâm đến mình với các sự kiện toán học và hiểu các thuộc tính của chúng.

Vì vậy, bạn không nên ngạc nhiên khi đưa ra bằng chứng chính xác tương đối không có lỗi: đó là điểm của toàn bộ "bài tập". (Tuy nhiên, điều này không có nghĩa là sai lầm không tồn tại hoặc hầu như không tồn tại, lỗi chỉ là con người, họ nói)

Bây giờ, nếu chúng ta xem xét lập trình, mục đích của chúng ta là gì? Chúng tôi không thực sự tìm kiếm sự hiểu biết, chúng tôi muốn một cái gì đó hoạt động . Nhưng khi nào một cái gì đó "làm việc"? Một cái gì đó hoạt động khi chúng ta đã tạo thành công một cái gì đó cho phép một số máy lạ hoàn thành nhiệm vụ mà chúng ta muốn nó thực hiện và tốt nhất là cũng khá nhanh.

Tôi tin rằng đây là sự khác biệt cơ bản, vì nó có nghĩa là mục tiêu của chúng tôi không thể chỉ đơn giản là một định lý mà chương trình của chúng tôi "chứng minh", chúng tôi mong muốn một cái gì đó trong thế giới thực (bất kể đó là gì), không phải là một tạo tác toán học. Điều này có nghĩa là về mặt lý thuyết chúng ta không thể đạt được mục tiêu của mình (mặc dù Dijkstra sẽ cho bạn thử nó một cách vô tư) vì chúng ta phải xoa dịu cỗ máy, hy vọng rằng chúng ta thực sự biết nhiệm vụ nào chúng ta muốn thực hiện và cũng nhận thức được những điều chưa được xem xét, chưa xảy ra bằng cách nào đó

Vì vậy, cuối cùng, không có cách nào khác ngoài việc chỉ thử nó và có thể thất bại, sửa chữa, thất bại và thử lại cho đến khi chúng tôi hài lòng với kết quả.


Lưu ý rằng giả thuyết của bạn viết bằng chứng không có lỗi đơn giản hơn các chương trình không có lỗi (thực tế là các tuyên bố khác nhau như @Ariel chỉ ra) trên thực tế có thể sai, vì bằng chứng thường được xây dựng thông qua thử nghiệm và lỗi ở một mức độ nào đó. Tuy nhiên, tôi hy vọng rằng điều này sẽ làm sáng tỏ câu hỏi được ngụ ý: "Điều gì thực sự khác biệt giữa việc chứng minh một số định lý và viết một chương trình?" (Mà một người quan sát bất cẩn về thư từ Curry-Howard có thể nói: "Không có gì cả!")


Như @wvxvw đã đề cập trong các bình luận, các đoạn sau từ 'ghi chú về Lập trình có cấu trúc' (EWD249, trang 21) rất phù hợp:

(...) Bản thân một chương trình không bao giờ là mục tiêu; Mục đích của chương trình là gợi lên các tính toán và mục đích của các tính toán là để thiết lập một hiệu ứng mong muốn. Mặc dù chương trình là sản phẩm cuối cùng được lập trình viên thực hiện, nhưng các tính toán có thể được gợi lên bởi nó - "chế tạo" được để lại cho máy! - là chủ đề thực sự của thương mại của mình. Ví dụ, bất cứ khi nào một lập trình viên nói rằng chương trình của anh ta là chính xác, anh ta thực sự đưa ra một khẳng định về các tính toán mà nó có thể gợi lên.

(...) Theo một nghĩa nào đó, việc tạo ra một chương trình vì thế khó hơn so với việc tạo ra một lý thuyết toán học: cả chương trình và lý thuyết đều có cấu trúc, các đối tượng vượt thời gian. Nhưng trong khi lý thuyết toán học có ý nghĩa như hiện tại, chương trình chỉ có ý nghĩa thông qua việc thực hiện.


2
Tôi chỉ là một giáo dân; Dijkstra đã thực sự đề cập đến điều gì khi "lập trình"?
Ovi

2
@Ovi Tôi không chắc chắn chính xác, nhưng sự khác biệt chính là anh ấy nói về vấn đề thuật toán (không tầm thường) giải quyết nhiều hơn các nhiệm vụ lập trình 'chung', tức là anh ấy chắc chắn không nói về một số chương trình CRUD cần kết nối một số chương trình CRUD cần kết nối một số Kiến trúc hiện có hoặc các thành phần khác, v.v. Có thể thấy nhiều hơn về ý kiến ​​lập trình của Dijkstra trong câu trả lời này
Thằn lằn rời rạc

3
Upvote để trích dẫn Dijkstra, nhưng bạn đã chọn sai địa điểm! Ông đã viết rất nhiều về vấn đề này trong các đoạn đầu tiên của Lập trình có cấu trúc. Tôi sẽ không muốn thay đổi câu trả lời của bạn bằng cách gửi một trích dẫn khác, nhưng tôi hy vọng bạn sẽ xem xét thêm từ bài báo đó vào câu trả lời của bạn!
wvxvw

@Ovi tôi đoán câu hỏi của bạn là lập trình trong thời gian của Dijkstra thường có nghĩa là viết mã lắp ráp so với thời đại hiện đại của các ngôn ngữ cấp cao. Tương tự, tôi đang đọc ấn bản năm 1974 của Tháng huyền thoại, các khái niệm vẫn còn hiện hành nhưng các tài liệu tham khảo kỹ thuật là trình biên dịch cấp hệ thống hoặc PL / I, khác nhiều so với hầu hết mọi người nghĩ về lập trình ngày nay
JimLohse

46

Lamport cung cấp một số căn cứ cho sự bất đồng về mức độ phổ biến của các lỗi trong các bằng chứng trong Cách viết một bằng chứng (trang 8-9) :

Khoảng hai mươi năm trước, tôi quyết định viết một bằng chứng về định lý Schroeder-Bernstein cho một lớp toán giới thiệu. Bằng chứng đơn giản nhất tôi có thể tìm thấy là trong văn bản cấu trúc liên kết chung cổ điển của Kelley. Vì Kelley đang viết cho một đối tượng tinh vi hơn, tôi đã phải thêm rất nhiều lời giải thích vào bằng chứng nửa trang của anh ấy. Tôi đã viết năm trang khi tôi nhận ra rằng bằng chứng của Kelley là sai. Gần đây, tôi muốn minh họa một bài giảng về phong cách chứng minh của mình bằng một bằng chứng không chính xác thuyết phục, vì vậy tôi đã chuyển sang Kelley. Tôi không thể tìm thấy điều gì sai với bằng chứng của anh ấy; Rõ ràng là nó đúng! Đọc và đọc lại bằng chứng đã thuyết phục tôi rằng hoặc là trí nhớ của tôi đã thất bại, hoặc nếu không thì tôi đã rất ngu ngốc hai mươi năm trước. Tuy nhiên, bằng chứng của Kelley rất ngắn và sẽ là một ví dụ điển hình, vì vậy tôi bắt đầu viết lại nó như một bằng chứng có cấu trúc.

... Phong cách này lần đầu tiên được áp dụng để chứng minh các định lý thông thường trong một bài báo tôi đã viết với Martin Abadi. Anh ấy đã viết bằng chứng thông thường bằng chứng bằng chứng là đủ tốt để thuyết phục chúng tôi và, có lẽ, các trọng tài. Viết lại các bằng chứng theo kiểu có cấu trúc, chúng tôi phát hiện ra rằng hầu hết mọi người đều có lỗi nghiêm trọng, mặc dù các định lý là chính xác. Mọi hy vọng rằng bằng chứng không chính xác có thể không dẫn đến các định lý không chính xác đã bị phá hủy trong lần hợp tác tiếp theo của chúng tôi. Hết lần này đến lần khác, chúng tôi sẽ đưa ra một phỏng đoán và viết một bản phác thảo bằng chứng trên bảng đen. Một bản phác thảo có thể dễ dàng biến thành một bằng chứng thông thường thuyết phục chỉ để khám phá, bằng cách cố gắng viết một bằng chứng có cấu trúc, rằng phỏng đoán đó là sai. Kể từ đó, tôi không bao giờ tin một kết quả mà không có bằng chứng cẩn thận, có cấu trúc.


6
Cùng một bài viết: "Bằng chứng giai thoại cho thấy rằng có đến một phần ba tất cả các bài báo được xuất bản trên các tạp chí toán học có lỗi - không chỉ là lỗi nhỏ, mà là các định lý và bằng chứng không chính xác". Chà, đó là vào những năm 90, nhưng hôm nay nó có khác không? Có lẽ những bài báo tồn tại những ngày đó, vẫn còn tồn tại và mọi thứ chồng chất ... Vì vậy, tôi không hoàn toàn tin rằng các bằng chứng toán học được cung cấp trong các bài báo chứa ít lỗi hơn.
MarkokraM

Giai thoại hấp dẫn, nhưng tôi không thấy rằng nó trực tiếp trả lời hoặc tham gia vào câu hỏi. Bạn có muốn chỉnh sửa câu trả lời của mình để trả lời trực tiếp hơn cho câu hỏi đã được hỏi không? Bạn có lập luận rằng các bằng chứng toán học cũng bị lỗi như viết mã máy tính? Bạn có thêm bằng chứng cho điều đó mà bạn có thể cung cấp? Một giai thoại hoặc hai không thực sự chứng minh điều đó, phải không?
DW

@DW Tôi gửi email cho Leslie nếu anh ta có thể đưa ra bằng chứng rõ ràng hơn cho yêu cầu bồi thường.
MarkokraM

3
@DW Leslie đã nói trong câu trả lời chân thành của mình rằng đồng nghiệp của anh ta đã thực hiện một cuộc điều tra với 51 bằng chứng được công bố trên Math Reviews tại thời điểm đó. Theo ý kiến ​​của ông, nó không chỉ là giai thoại nhưng không phù hợp với bằng chứng mạnh mẽ do một số sự kiện. Trường hợp phức tạp hơn vì một số lỗi về bằng chứng xảy ra do họ đã sử dụng bằng chứng sai lầm được quảng cáo trước đó, vv Sẽ là một chủ đề nghiên cứu tuyệt vời nhưng đòi hỏi rất nhiều công việc. Làm thế nào để xác minh bằng chứng toán học lập trình vẫn là một câu hỏi lớn. Các ứng dụng được thực hiện để hỗ trợ bằng chứng tương tác đang ở giai đoạn rất sớm. Ít nhất là giao diện của chúng.
MarkokraM

@DW Các hoặc hai giai thoại cho thấy cách một chứng minh toán học có thể xuất hiện "đúng" nhưng thực sự là không lành mạnh. Đối với bất kỳ ai vừa viết một thuật toán máy tính phức tạp vừa thực hiện một bằng chứng toán học, và đã cố gắng viết một thuật toán máy tính như một bằng chứng toán học và sau đó khám phá ra "thuật toán" cấp độ cao bị phản bội bởi nhiều, rất nhiều lỗi trong chi tiết, kết quả không có gì đáng ngạc nhiên cả
Yakk

39

Một sự khác biệt lớn là các chương trình thường được viết để hoạt động trên các đầu vào, trong khi các bằng chứng toán học thường bắt đầu từ một tập hợp tiên đề và các định lý đã biết trước. Đôi khi bạn phải bao gồm nhiều trường hợp góc để có được bằng chứng tổng quát, nhưng các trường hợp và độ phân giải của chúng được liệt kê rõ ràng và phạm vi của kết quả bị ràng buộc ngầm đối với các trường hợp được bảo hiểm.

So sánh điều này với một chương trình máy tính, phải cung cấp đầu ra 'chính xác' cho một loạt các đầu vào có thể. Rất hiếm khi có thể liệt kê tất cả các yếu tố đầu vào và thử tất cả chúng. Tệ hơn nữa, giả sử chương trình tương tác với một con người và cho phép đầu vào của họ sửa đổi chức năng? Con người nổi tiếng là không thể đoán trước và số lượng đầu vào có thể cho một chương trình lớn hợp lý với sự tương tác của con người tăng lên với tốc độ phi thường. Bạn cần cố gắng thấy trước tất cả các cách khác nhau mà chương trình có thể được sử dụng và cố gắng làm cho tất cả các trường hợp sử dụng đó hoạt động hoặc ít nhất là thất bại một cách hợp lý, khi thất bại là lựa chọn duy nhất. Và đó là giả sử bạn thậm chí không biết làm thế nào nó phải làm việc trong tất cả những trường hợp góc tối nghĩa.

Cuối cùng, một chương trình lớn thực sự không thể so sánh với một bằng chứng duy nhất, thậm chí là một bằng chứng phức tạp. Một chương trình lớn có lẽ gần giống với việc thu thập và xem xét một thư viện văn học nhỏ, một số trong đó có thể có lỗi mà bạn cần phải làm việc xung quanh. Đối với các chương trình dựa trên quy mô của một bằng chứng duy nhất, có thể là một triển khai thuật toán nhỏ, giả sử, các kỹ sư phần mềm có kinh nghiệm có thể / hoàn thành chúng mà không mắc lỗi, đặc biệt là khi sử dụng các công cụ hiện đại ngăn chặn / giải quyết các lỗi nhỏ phổ biến (như lỗi chính tả ) tương đương với các vấn đề ban đầu mà bạn giải quyết trong hiệu đính.


14
+1 cho đoạn cuối cùng của bạn. Mặc dù các bằng chứng toán học về nguyên tắc được xây dựng dựa trên nhau, thông thường các kiến ​​thức cơ bản được hiểu rõ, sự tương tự của các thư viện máy tính (mặc dù chúng cũng có lỗi ...), và bằng chứng thực tế không quá dài. Ngược lại, phần mềm tiêu dùng dài và phức tạp, và do đó có nhiều cơ hội hơn để thất bại.
Yuval Filmus

6
Trong thực tế, vấn đề khác với phần mềm tiêu dùng là hành vi 'chính xác' thường được xác định kém về phía trước và do đó, những gì được sử dụng để sửa sau này trở nên sai. Nó sẽ giống như cố gắng viết một bằng chứng chỉ để tìm ra rằng mọi người đã quyết định thay đổi các tiên đề. Bạn có thể sửa nó trong ký hiệu, phải không?
Dan Bryant

2
@DanBryant Tình huống đó xảy ra trong toán học. Cụ thể, các định nghĩa về thuật ngữ thay đổi theo thời gian và thường mơ hồ ngay cả khi chúng được sử dụng. "Bằng chứng và bác bỏ" của Imre Lakatos mô tả điều này với thuật ngữ "đa giác". Một điều tương tự đã xảy ra với "chức năng" và ở mức độ thấp hơn "tích phân". Ngay cả ngày nay, "phạm trù" không rõ ràng và các bằng chứng và định lý có thể thất bại tùy thuộc vào ý nghĩa chính xác của bạn.
Derek Elkins

25

Họ nói rằng vấn đề với máy tính là họ làm chính xác những gì bạn nói với họ.

Tôi nghĩ rằng đây có thể là một trong nhiều lý do.

Lưu ý rằng, với một chương trình máy tính, người viết (bạn) thông minh nhưng người đọc (CPU) bị câm.
Nhưng với một bằng chứng toán học, người viết (bạn) thông minh và người đọc (người đánh giá) cũng thông minh.

Điều này có nghĩa là bạn không bao giờ có đủ khả năng để tham gia vào một tình huống "tốt, bạn biết ý tôi gì " với máy tính. Nó làm chính xác những gì bạn nói với nó, mà không biết ý định của bạn.

Ví dụ: giả sử đây là một bước trong một số bằng chứng:

x2+4x+3x+3=(x+1)(x+3)x+3=x+1

Nếu bạn bảo một máy tính đánh giá và sau đó chia nó cho , nó sẽ làm nghẹt chương trình của bạn khi bạn để . Nhưng một nhà toán học sẽ không bị mắc kẹt về điểm này một cách không cần thiết. Anh ta sẽ nhận ra rằng điều này rất có thể không liên quan đến điểm mà bạn đang cố gắng thực hiện, và việc từ bỏ và phàn nàn về vấn đề nhỏ này sẽ không giúp được ai. Anh ta sẽ hiểu ý bạn vì anh ta không chỉ theo bạn; anh ấy hiểu bạn Khó thất bại hơn khi người đọc của bạn thông minh.x + 3 x = - 3x2+4x+3x+3x=3


3
Câu trả lời chính xác! ngoại trừ việc là một máy tính, tôi phản đối việc bạn sử dụng từ "không cần thiết". ;) [Giả sử đây chỉ là một bước trong một bằng chứng lớn hơn nhằm chứng minh rằng đó -xlà hợp chất. Thực tế là bước này sai khi -x = 3có liên quan cao đến tính chính xác của bằng chứng hoàn thành!]
Quuxplusone

@Quuxplusone: = P
Mehrdad

Máy tính cũng có thể sử dụng các quy tắc viết lại biểu tượng và toán học không xác định, chỉ là các ngôn ngữ chúng ta sử dụng như C ++ đều ở mức rất thấp và dựa trên công nghệ cổ đại (ví dụ C có ít tính năng hơn Algol 60). Các ngoại lệ duy nhất là các ngôn ngữ chứng minh / kiểm tra như Idris / Agda, Lisp với các bộ giải biểu tượng và Mathicala. ja.wolframalpha.com/input/ đá
aoeu256

23

Một vấn đề mà tôi nghĩ không được giải quyết trong câu trả lời của Yuval, đó là dường như bạn đang so sánh các loài động vật khác nhau.

nn!

Xác minh các thuộc tính ngữ nghĩa của các chương trình là không thể xác định được (định lý của Rice) và tương tự, kiểm tra xem một câu lệnh trong logic vị ngữ thứ tự đầu tiên có đúng hay không cũng không thể xác định được. Vấn đề là không có sự khác biệt thực sự về độ cứng so với cách bạn nhìn nhận vấn đề. Mặt khác, chúng ta có thể suy luận về các thuộc tính cú pháp của các chương trình (trình biên dịch) và điều này tương tự với thực tế là chúng ta có thể xác minh bằng chứng. Lỗi (mã không làm những gì tôi muốn) là ngữ nghĩa, vì vậy bạn nên so sánh chúng với đối tác chính xác của chúng.

Tôi sẽ củng cố Yuval và nói rằng toàn bộ các lĩnh vực đã phát triển với động lực viết các bằng chứng toán học có thể được viết và xác minh trong một số hệ thống chính thức, vì vậy ngay cả quá trình xác minh cũng không hề nhỏ.


18

Có gì khác nhau khi viết bằng chứng toán học không có lỗi và viết mã máy tính không có lỗi khiến cho cái trước trở nên dễ điều khiển hơn cái sau?

Tôi tin rằng các lý do chính là sự không ổn định (cho cùng kết quả cho cùng một đầu vào) và tính không thay đổi (không thay đổi).

Điều gì xảy ra nếu một bằng chứng toán học có thể cho kết quả khác nhau nếu nó được đọc vào thứ ba hoặc khi năm tiến lên năm 2000 từ năm 1999? Điều gì sẽ xảy ra nếu một phần của một bằng chứng toán học là quay lại một vài trang, viết lại một vài dòng, và sau đó bắt đầu lại từ thời điểm đó?

Tôi chắc chắn rằng một bằng chứng như vậy sẽ dễ bị lỗi như một đoạn mã máy tính bình thường.

Tôi cũng thấy các yếu tố phụ khác:

  1. Các nhà toán học thường được giáo dục nhiều hơn trước khi cố gắng viết một bằng chứng quan trọng / có thể xuất bản. 1/4 nhà phát triển chuyên nghiệp có tiêu đề tự bắt đầu viết mã cách đây chưa đầy 6 năm (xem khảo sát SO 2017 ), nhưng tôi cho rằng hầu hết các nhà toán học có hơn một thập kỷ giáo dục toán chính thức.
  2. Bằng chứng toán học hiếm khi được giữ ở mức độ xem xét kỹ lưỡng như mã máy tính. Một lỗi đánh máy có thể / sẽ phá vỡ một chương trình, nhưng hàng tá lỗi chính tả có thể không đủ để phá hủy giá trị của một bằng chứng (chỉ khả năng đọc của nó).
  3. Ma quỷ trong các chi tiết và mã máy tính không thể bỏ qua chi tiết. Bằng chứng là miễn phí để bỏ qua các bước được coi là đơn giản / thói quen. Có một số loại đường cú pháp đẹp có sẵn trong các ngôn ngữ hiện đại, nhưng đây là những loại mã hóa cứng và khá hạn chế khi so sánh.
  4. Toán học cũ hơn và có một nền tảng / cốt lõi vững chắc hơn. Chắc chắn có rất nhiều trường con mới và sáng bóng trong toán học, nhưng hầu hết các nguyên tắc cốt lõi đã được sử dụng trong nhiều thập kỷ. Điều này dẫn đến sự ổn định. Mặt khác, các lập trình viên vẫn không đồng ý về phương pháp mã hóa cơ bản (chỉ cần hỏi về sự phát triển của Agile và tỷ lệ chấp nhận nó).

Có thể đáng nói đến việc lập trình 'tương đương' của chương trình là độ tinh khiết về chức năng , được công nhận và hỗ trợ trong một số ngôn ngữ như Haskell.
Pharap

12

Tôi đồng ý với những gì Yuval đã viết. Nhưng cũng có một câu trả lời đơn giản hơn nhiều: Trong thực tế, các kỹ sư phần mềm thường không cố kiểm tra tính chính xác của chương trình của họ, họ chỉ đơn giản là không, họ thường không viết ra các điều kiện xác định khi chương trình đúng.

Có nhiều lý do cho nó. Một là hầu hết các kỹ sư phần mềm không có kỹ năng hình thành rõ ràng các vấn đề về mặt toán học cũng như họ không biết cách viết bằng chứng chính xác.

Một điều nữa là việc xác định các điều kiện chính xác cho một hệ thống phần mềm phức tạp (đặc biệt là một hệ thống phân tán) là một nhiệm vụ rất khó khăn và tốn thời gian. Họ dự kiến ​​sẽ có một cái gì đó dường như hoạt động trong vài tuần.

Một lý do khác là tính đúng đắn của một chương trình phụ thuộc vào nhiều hệ thống khác được viết bởi những hệ thống khác mà không có ngữ nghĩa rõ ràng. Có một luật của Hyrum về cơ bản nói rằng nếu thư viện / dịch vụ của bạn có hành vi có thể quan sát được (không phải là một phần của hợp đồng) thì cuối cùng sẽ có người phụ thuộc vào nó. Điều đó về cơ bản có nghĩa là ý tưởng phát triển phần mềm ở dạng mô-đun với các hợp đồng rõ ràng như bổ đề trong toán học không hoạt động trong thực tế. Nó trở nên tồi tệ hơn trong các ngôn ngữ sử dụng sự phản chiếu. Ngay cả khi một chương trình là chính xác ngày hôm nay, nó có thể bị hỏng vào ngày mai khi ai đó thực hiện một số tái cấu trúc tầm thường trong một trong những phụ thuộc của nó.

Trong thực tế những gì thường xảy ra là họ có các bài kiểm tra. Các xét nghiệm hoạt động như những gì được mong đợi từ chương trình. Mỗi khi tìm thấy một lỗi mới, họ thêm các bài kiểm tra để bắt nó. Nó hoạt động đến một số mở rộng, nhưng nó không phải là một bằng chứng chính xác.

Khi mọi người không có kỹ năng xác định tính chính xác cũng như không viết chương trình chính xác cũng như không mong muốn làm điều đó và làm điều đó khá khó khăn, không có gì ngạc nhiên khi phần mềm không chính xác.

Nhưng cũng lưu ý rằng vào cuối ở những nơi tốt hơn, kỹ thuật phần mềm được thực hiện bằng cách xem lại mã. Đó là tác giả của một chương trình phải thuyết phục ít nhất một người khác rằng chương trình hoạt động chính xác. Đó là điểm một số đối số cấp cao không chính thức được đưa ra. Nhưng một lần nữa điển hình không có gì gần với một định nghĩa nghiêm ngặt rõ ràng về tính đúng đắn hoặc bằng chứng về tính đúng đắn xảy ra.

Trong toán học người ta tập trung vào tính đúng đắn. Trong phát triển phần mềm, có rất nhiều điều mà một lập trình viên cần quan tâm và có sự đánh đổi giữa chúng. Có một phần mềm không có lỗi hoặc thậm chí là một định nghĩa đúng về tính chính xác (với các yêu cầu thay đổi theo thời gian) là một lý tưởng, nhưng nó phải được đánh đổi để chống lại các yếu tố khác và một trong những điều quan trọng nhất trong số đó là dành thời gian để phát triển nó. nhà phát triển. Vì vậy, trong thực tế ở những nơi tốt hơn, mục tiêu và quy trình đang giảm thiểu rủi ro lỗi càng nhiều càng khả thi thay vì làm cho phần mềm không có lỗi.


Tôi thực sự không chắc ai là người tồi tệ hơn giữa các lập trình viên và nhà toán học chính thức (tức là theo cách kiểm tra bằng máy) xây dựng các thông số kỹ thuật chính xác và chứng minh mã chính xác cho chương trình 10KLOC hoặc lớn hơn. Một mặt, bạn hoàn toàn chính xác rằng hầu hết các lập trình viên không có kỹ năng chứng minh định lý được phát triển tốt. Mặt khác, các bằng chứng chính thức lớn giống như các chương trình lớn và đòi hỏi các kỹ năng kỹ thuật phần mềm cơ bản để quản lý. Tôi hoàn toàn tin tưởng bất kỳ bằng chứng chính thức nào về tính đúng đắn của một chương trình như vậy sẽ không có hy vọng là đúng.
Derek Elkins

Có lẽ. Trong mọi trường hợp và chỉ để làm rõ, tôi không lấy bằng chứng chính thức trong câu trả lời của mình, chỉ là bằng chứng không chính thức ở cấp độ mà chúng ta thấy nói trong các bài báo thuật toán.
Kaveh

11

Có rất nhiều câu trả lời hay nhưng vẫn còn nhiều lý do toán học và lập trình không giống nhau.

1 Bằng chứng toán học có xu hướng đơn giản hơn nhiều so với các chương trình máy tính. Hãy xem xét các bước đầu tiên của một bằng chứng giả thuyết:

Đặt một số nguyên

Đặt b là số nguyên

Đặt c = a + b

Cho đến nay bằng chứng là tốt. Hãy biến điều đó thành những bước đầu tiên của một chương trình tương tự:

Đặt a = input ();

Đặt b = đầu vào ();

Đặt c = a + b;

Chúng tôi đã có vô số vấn đề. Giả sử rằng người dùng thực sự đã nhập một số nguyên, chúng ta phải kiểm tra giới hạn. Là một lớn hơn -32.768 (hoặc bất cứ int phút trên hệ thống của bạn)? Là một ít hơn 32767? Bây giờ chúng ta phải kiểm tra điều tương tự cho b . Và bởi vì chúng tôi đã thêm ab , chương trình không chính xác trừ khi a + blớn hơn -32768 và nhỏ hơn 32767. Đó là 5 điều kiện riêng biệt mà một lập trình viên phải lo lắng về việc một nhà toán học có thể bỏ qua. Lập trình viên không chỉ phải lo lắng về họ, anh ta còn phải tìm ra những việc cần làm khi một trong những điều kiện đó không được đáp ứng và viết mã để làm bất cứ điều gì anh ta quyết định là cách xử lý các điều kiện đó. Toán học rất đơn giản. Lập trình rất khó.

2 Người hỏi không nói liệu anh ta có đề cập đến lỗi thời gian biên dịch hay lỗi thời gian chạy hay không, nhưng các lập trình viên thường không quan tâm đến lỗi thời gian biên dịch. Trình biên dịch tìm thấy chúng và chúng dễ dàng sửa chữa. Chúng giống như lỗi chính tả. Làm thế nào thường xuyên mọi người gõ một số đoạn văn mà không có lỗi lần đầu tiên?

3 Đào tạo.Từ khi còn rất nhỏ chúng ta được dạy làm toán và chúng ta phải đối mặt với hậu quả của những lỗi nhỏ lặp đi lặp lại. Một nhà toán học được đào tạo đã phải bắt đầu giải các bài toán đại số nhiều bước thường ở trường trung học và phải làm hàng tá (hoặc nhiều hơn) các bài toán như vậy mỗi tuần trong một năm. Một dấu hiệu tiêu cực đã giảm khiến toàn bộ vấn đề bị sai. Sau đại số các vấn đề trở nên dài hơn và khó khăn hơn. Các lập trình viên, mặt khác, thường được đào tạo ít chính thức hơn nhiều. Nhiều người tự học (ít nhất là ban đầu) và không được đào tạo chính thức cho đến khi học đại học. Ngay cả ở cấp đại học, các lập trình viên phải học khá nhiều lớp toán trong khi các nhà toán học có thể học một hoặc hai lớp lập trình.


10

Tôi thích câu trả lời của Yuval, nhưng tôi muốn xem lại nó một chút. Một lý do bạn có thể thấy dễ dàng hơn khi viết các bằng chứng Toán học có thể hiểu rõ hơn về bản thể học toán học thuần túy như thế nào. Để xem những gì tôi muốn nói, hãy xem xét những điều sau đây:

  • Các hàm trong Toán học là thuần túy (toàn bộ kết quả của việc gọi một hàm được gói gọn hoàn toàn trong giá trị trả về, là giá trị xác định và được tính toán hoàn toàn từ giá trị đầu vào).
  • Toán học không có đột biến hoặc phân công lại (khi bạn cần mô hình hóa những thứ đó, các hàm và chuỗi được sử dụng).
  • Toán học được minh bạch tham chiếu (ví dụ: không có con trỏ, không có khái niệm gọi theo tên so với gọi theo giá trị) và các đối tượng toán học có ngữ nghĩa bình đẳng mở rộng (nếu "hai" mọi thứ đều giống nhau theo mọi cách có thể quan sát được, thì thực tế chúng là giống nhau cả thôi).

Mặc dù có thể tranh luận liệu các hạn chế trên có làm cho việc viết chương trình trở nên dễ dàng hơn hay không, tôi nghĩ rằng có những thỏa thuận rộng rãi rằng các hạn chế trên giúp cho việc lập luận về chương trình trở nên dễ dàng hơn. Điều chính bạn làm khi viết một bằng chứng Toán học là lý do về bằng chứng bạn đang viết (vì, không giống như trong lập trình, bạn không bao giờ phải nhân đôi nỗ lực trong Toán học vì trừu tượng là miễn phí), do đó, nói chung là đáng để nhấn mạnh vào hạn chế trên.


7

Bằng chứng toán học cơ bản không tương đương với một ứng dụng trong thế giới thực, được thiết kế để đáp ứng nhu cầu của con người sống.

Con người sẽ thay đổi mong muốn, nhu cầu và yêu cầu của họ về những gì có thể là cơ sở hàng ngày trong lĩnh vực chương trình máy tính.

Có gì khác nhau khi viết bằng chứng toán học không có lỗi và viết mã máy tính không có lỗi khiến cho cái trước trở nên dễ điều khiển hơn cái sau?

Với một yêu cầu rõ ràng như một vấn đề toán học, một chương trình không có lỗi có thể được viết. Chứng minh rằng thuật toán của Dijkstra có thể tìm thấy con đường ngắn nhất giữa hai điểm trên biểu đồ không giống như thực hiện một chương trình chấp nhận đầu vào tùy ý và tìm điểm ngắn nhất giữa hai điểm bất kỳ trong đó.

Có bộ nhớ, hiệu suất và mối quan tâm phần cứng để quản lý. Tôi ước chúng ta không thể nghĩ về những điều đó khi viết thuật toán, rằng chúng ta có thể sử dụng các cấu trúc thuần túy và chức năng để quản lý điều này, nhưng các chương trình máy tính sống trong thế giới phần cứng "thực" trong khi bằng chứng toán học nằm trong ... "lý thuyết".


Hoặc, để ngắn gọn hơn :

nhập mô tả hình ảnh ở đây


4

Nhìn nó từ một góc độ khác, trong một môi trường phi học thuật, nó thường liên quan đến tiền.

Như các bài viết khác khẳng định tốt, Toán học là một đặc tả trừu tượng duy nhất, do đó, một bằng chứng cần phải hoạt động nhất quán trong phạm vi thông số kỹ thuật đó để được chứng minh. Một chương trình máy tính có thể hoạt động dựa trên nhiều triển khai của đặc tả trừu tượng của toán học - nghĩa là cách một ngôn ngữ hoặc nhà sản xuất phần cứng thực hiện toán học dấu phẩy động có thể hơi khác so với ngôn ngữ khác có thể gây ra biến động nhẹ trong kết quả.

Như vậy, 'chứng minh' một chương trình máy tính trước khi viết nó sẽ liên quan đến việc chứng minh logic ở cấp độ phần cứng, cấp độ hệ điều hành, trình điều khiển, ngôn ngữ lập trình, trình biên dịch, có thể là thông dịch viên, cho mọi kết hợp phần cứng có thể có của chương trình có thể hiểu được có thể được chạy trên và bất kỳ dữ liệu có thể hiểu được mà nó có thể ăn vào. Bạn có thể sẽ tìm thấy mức độ chuẩn bị và hiểu biết này về các sứ mệnh không gian, hệ thống vũ khí hoặc hệ thống kiểm soát năng lượng hạt nhân, trong đó thất bại có nghĩa là hàng chục tỷ đô la bị mất và có khả năng mất nhiều mạng sống, nhưng không nhiều thứ khác.

Đối với lập trình viên và / hoặc doanh nghiệp 'hàng ngày' của bạn, sẽ hiệu quả hơn rất nhiều về chi phí khi chấp nhận một mức độ chính xác nhất định trong mã chính xác và bán một sản phẩm có thể sử dụng được và các nhà phát triển có thể sửa chữa lỗi khi chúng bị phát hiện trong quá trình sử dụng.


3
Bạn dường như có một cái nhìn hạn hẹp về toán học là gì và một cái nhìn quá rộng mở về những gì "chứng minh" một chương trình máy tính đòi hỏi. Bạn không cần phải chứng minh toàn bộ hệ thống chính xác để chứng minh một chương trình đúng, bạn chỉ cần chứng minh rằng nó đúng khi giả sử các thành phần khác đáp ứng các thông số kỹ thuật của chúng. Nếu họ không, đó không phải là lỗi chương trình của bạn. Mặt khác, nếu chương trình của bạn bị hỏng vì nó phụ thuộc vào các chi tiết không phải là một phần của đặc điểm kỹ thuật của các thành phần đó, ví dụ như các biến thể triển khai của IEEE754, thì đó lỗi của bạn.
Derek Elkins

Nhận xét công bằng. Tôi có thể đang lạm dụng một số thuật ngữ vì nó không phải là nền tảng học vấn của tôi. Mặc dù tôi cảm thấy rằng giả định rằng các thành phần khác là hoàn hảo không phải là một điều khôn ngoan để làm, do những bình luận trước đây của tôi.
hoa tiêu_

4

Tôi nghĩ rằng lý luận của bạn là hợp lệ, nhưng đầu vào của bạn thì không. Bằng chứng toán học đơn giản là không có khả năng chịu lỗi hơn các chương trình, nếu cả hai đều được viết bởi con người. Dijkstra đã được trích dẫn ở đây, nhưng tôi sẽ cung cấp một trích dẫn bổ sung.

Tuy nhiên, chúng ta phải tổ chức các tính toán theo cách sao cho sức mạnh hạn chế của chúng ta đủ để đảm bảo rằng việc tính toán sẽ thiết lập hiệu quả mong muốn. Tổ chức này bao gồm các thành phần của chương trình và ở đó chúng tôi phải đối mặt với vấn đề tiếp theo về kích thước, viz. độ dài của văn bản chương trình, và chúng ta cũng nên đưa ra vấn đề này. Chúng ta nên nhận thức được thực tế rằng mức độ chúng ta có thể đọc hoặc viết một văn bản phụ thuộc rất nhiều vào kích thước của nó. [...]

Đó là trong cùng một tâm trạng mà tôi muốn thu hút sự chú ý của người đọc về thực tế rằng "sự rõ ràng" đã phát âm các khía cạnh định lượng, một thực tế mà nhiều nhà toán học, đủ tò mò, dường như không biết. Một định lý nêu rõ tính hợp lệ của một kết luận khi mười trang đầy đủ các điều kiện được thỏa mãn hầu như không phải là một công cụ thuận tiện, vì tất cả các điều kiện phải được xác minh bất cứ khi nào định lý được kháng cáo. Trong hình học Euclide, Định lý Pythagoras giữ cho ba điểm A, B và C bất kỳ để qua A và C, một đường thẳng có thể được vẽ trực giao thành một đường thẳng qua B và C. Có bao nhiêu nhà toán học đánh giá rằng định lý này vẫn có thể áp dụng khi một số hoặc tất cả các điểm A, B và C trùng nhau? tuy nhiên điều này dường như chịu trách nhiệm lớn cho sự thuận tiện mà Định lý Pythagoras có thể được sử dụng.

Tóm tắt: là một con người chậm chạp, tôi có một cái đầu rất nhỏ và tôi nên học cách sống với nó và tôn trọng những hạn chế của mình và cho họ tín dụng đầy đủ, thay vì cố gắng phớt lờ chúng, vì nỗ lực vô ích sau này sẽ là bị trừng phạt bởi thất bại.

Điều này được chỉnh sửa một chút ba đoạn cuối từ chương đầu tiên của Lập trình có cấu trúc của Dijkstra.

Để có thể viết lại điều này, để áp dụng tốt hơn cho câu hỏi của bạn: tính chính xác phần lớn là một chức năng của kích thước bằng chứng của bạn. Tính chính xác của các bằng chứng toán học dài là rất khó để thiết lập (rất nhiều "bằng chứng" được công bố sống trong tình trạng không chắc chắn do không ai thực sự xác minh chúng). Nhưng, nếu bạn so sánh tính đúng đắn của các chương trình tầm thường với bằng chứng tầm thường, có khả năng không có sự khác biệt đáng chú ý nào. Tuy nhiên, các trợ lý chứng minh tự động (theo nghĩa rộng hơn, trình biên dịch Java của bạn cũng là một trợ lý chứng minh), hãy để các chương trình giành chiến thắng bằng cách tự động hóa rất nhiều nền tảng.


Bạn có ý nghĩa gì bởi "bằng chứng toán học dài"? Bằng chứng của định lý đồ thị nhỏ là khá dài, nhưng nó không thực sự bị tranh chấp bởi bất kỳ ai. Định lý Feit-Thompson có một bằng chứng khá dài, nhưng chưa bao giờ thực sự ở trạng thái lấp lửng. Làm thế nào để bạn so sánh độ dài của bằng chứng và chương trình? Số từ? Có thực sự không có sự khác biệt đáng chú ý giữa bằng chứng và chương trình khi bạn so sánh bằng chứng và chương trình có độ phức tạp tương tự (độ dài)?
Yuval Filmus

@YuvalFilmus giống như trong đoạn trích dẫn: mười trang khẳng định là dài đối với con người. Làm thế nào để tôi đánh giá về độ dài của một chương trình? Chà, Dikstra đã đưa ra một số liệu: độ dài của văn bản. Tôi nghĩ rằng nó có thể quá đơn giản, nhưng nó vẫn là một heuristic tốt. Có những số liệu khác, thú vị hơn, ví dụ như độ phức tạp theo chu kỳ
wvxvw

3

Như các câu trả lời khác đã chạm vào trong câu trả lời của họ (tôi muốn giải thích), nhưng một phần lớn của vấn đề là việc sử dụng thư viện. Ngay cả với tài liệu hoàn hảo (phổ biến như mã không có lỗi), không thể chuyển toàn bộ kiến ​​thức về thư viện cho mọi lập trình viên sử dụng thư viện. Nếu lập trình viên không hiểu hoàn hảo thư viện của họ, họ có thể mắc lỗi khi sử dụng nó. Đôi khi những lỗi này có thể dẫn đến các lỗi nghiêm trọng được phát hiện khi mã không hoạt động. Nhưng đối với các lỗi nhỏ, chúng có thể không được chú ý.

Một tình huống tương tự sẽ xảy ra nếu một nhà toán học sử dụng các bằng chứng và bổ đề hiện có mà không hiểu đầy đủ về chúng; bằng chứng của riêng họ có thể sẽ bị thiếu sót. Trong khi điều này có thể gợi ý một giải pháp là học hoàn hảo mọi thư viện mà người ta sử dụng; điều này thực tế rất tốn thời gian và có thể đòi hỏi kiến ​​thức miền mà lập trình viên không có. (Tôi biết rất ít về trình tự DNA / tổng hợp protein; nhưng vẫn có thể làm việc với các khái niệm này bằng thư viện).

Nói ngắn gọn hơn, công nghệ phần mềm (nói chung là kỹ thuật thực sự) dựa trên việc gói gọn các mức độ trừu tượng khác nhau để cho phép mọi người tập trung vào các lĩnh vực nhỏ hơn của vấn đề mà họ chuyên môn hóa. Điều này cho phép mọi người phát triển chuyên môn trong lĩnh vực của họ, nhưng cũng đòi hỏi giao tiếp tuyệt vời giữa mỗi lớp. Khi giao tiếp đó không hoàn hảo, nó sẽ gây ra vấn đề.


3
Đợi đã, điều gì khiến bạn nghĩ rằng các nhà toán học "hiểu đầy đủ" các bằng chứng và bổ đề mà họ sử dụng? Tôi không chắc sự khác biệt giữa các nhà toán học và lập trình viên mà bạn đang cố gắng chứng minh ở đây.
Derek Elkins

3

Tôi sẽ cố gắng trở thành bản gốc sau tất cả những câu trả lời tuyệt vời đó.

Chương trình bằng chứng

Sự đồng hình hóa Curry Curry Howard cho chúng ta biết, các loại trong chương trình của bạn là các định lý và mã thực tế là bằng chứng của chúng.

Phải thừa nhận rằng, đây là một cái nhìn rất trừu tượng và cao cấp. Vấn đề mà bạn, có lẽ, có nghĩa là, việc viết một mã điển hình khó hơn vì nó quá thấp. Trong hầu hết các trường hợp, bạn "cần nói cho máy biết phải làm gì". Hoặc, để xem xét điều này từ cách khác: các nhà toán học thực sự giỏi về sự trừu tượng.

Như một lưu ý phụ: "Âm nhạc của những dòng suối" là một trong những cây cầu đẹp nhất giữa cả hai. Về cơ bản nó thiết lập mọi thứ để có thể nói "Tôi muốn này trong đó cách" và máy kỳ diệu làm này chính xác như mong muốn.


Tôi không hoàn toàn nhìn thấy nếu điều này giải quyết câu hỏi. OP đã không đưa ra bất kỳ dấu hiệu nào cho thấy họ đang nói về các ngôn ngữ lập trình với các hệ thống loại mạnh mẽ và tôi nghĩ chúng có nghĩa là các hệ thống loại chung chung hơn. Vì vậy, Curry-Howard là loại tầm thường trong trường hợp này.
6005

Tôi biết đó là một chút xa vời cho C hoặc những thứ tương tự. Nhưng quan điểm của tôi là: toán học gần hơn một người mới bắt đầu CS điển hình có thể nghĩ!
Oleg lobachev

1
Có vẻ như bạn là một 'người quan sát bất cẩn' về sự đồng hình của Curry-Howards, mà tôi đã đề cập đến trong câu trả lời của mình. Ngay cả khi chúng ta có sự đồng hình giữa các chương trình và bằng chứng, thì nó cũng không tuân theo hành động viết chương trình và viết bằng chứng là tương tự nhau. Trên thực tế, thậm chí có thể xảy ra trường hợp tất cả các chương trình 'thú vị' hoặc 'điển hình' không tương ứng với một bằng chứng điển hình và ngược lại.
Thằn lằn rời rạc

@Discretelizard Thật không phải là trường hợp các chương trình "thú vị" không tương ứng với một "bằng chứng điển hình". Đây là một ví dụ trong đó tôi lấy "bằng chứng điển hình" của ai đó và tạo ra một (bản phác thảo) một chương trình thú vị không thể chối cãi (một cái gì đó liên quan chặt chẽ đến việc loại bỏ Gaussian). Được trang bị các loại chính xác phù hợp, tôi nghĩ rằng hầu hết các chương trình "thú vị" sẽ là bổ đề hoặc định lý hữu ích, nhưng nhiều bằng chứng (mang tính xây dựng) không có ý nghĩa tính toán thực sự - chúng chỉ là xác minh các điều kiện phụ - mặc dù rất nhiều điều.
Derek Elkins

3

Không có câu trả lời nào khác chỉ ra những điều sau đây. Bằng chứng toán học hoạt động trên các hệ thống máy tính tưởng tượng có bộ nhớ vô hạn và sức mạnh tính toán vô hạn. Do đó, họ có thể giữ số lượng lớn tùy ý đến độ chính xác vô hạn và không mất độ chính xác trong bất kỳ phép tính nào.

π


2
"Bằng chứng toán học hoạt động trên các hệ thống máy tính tưởng tượng có bộ nhớ vô hạn và sức mạnh tính toán vô hạn." Hầu hết các bằng chứng toán học 'hoạt động' trên các hệ thống đại số chính thức, ví dụ như các số thực (nơi chúng ta có 'độ chính xác vô hạn'). Điều này cũng có thể được thực hiện trong các chương trình: có cái gọi là hệ thống đại số máy tính (CAS) thực hiện chính xác điều này! Hơn nữa, toàn bộ các lĩnh vực toán học quan tâm đến thực tế là chúng ta không thể biểu diễn tất cả các số thực chính xác như các số dấu phẩy động hữu hạn. Tôi nghĩ rằng bạn đang phân biệt giữa toán học và lập trình, nơi không có.
Thằn lằn rời rạc

1
@Discretelizard, vâng, các gói đặc biệt tồn tại với độ chính xác tùy ý, nhưng ngay cả khi đó, bộ nhớ khả dụng sẽ hạn chế độ chính xác có thể đạt được thực tế. Ngoài ra chúng là những gói đặc biệt . Chỉ có một tỷ lệ nhỏ lập trình được thực hiện với các gói như vậy, và chủ yếu là trong môi trường học thuật.
crobar

π

@Discretelizard, tôi nghĩ rằng quan điểm của tôi vẫn đứng vững, hầu hết các lập trình viên không sử dụng các hệ thống CAS như vậy. Chúng quá chậm đối với lập trình trong thế giới thực. Hầu hết các chương trình về cơ bản liên quan đến các hoạt động trên số lượng chính xác hạn chế. Các ngôn ngữ hàng đầu là C, C ++, Python, Java, v.v ... không sử dụng biểu diễn kiểu CAS theo mặc định (mặc dù các gói để làm điều này có thể được tạo trong chúng). Ví dụ của bạn là một tập hợp con nhỏ của ngôn ngữ / hệ thống máy tính.
crobar

2
@crobar Vấn đề với câu trả lời của bạn là phần lớn các lỗi được phát hiện không phải do lỗi dấu phẩy động hoặc tràn số nguyên (mặc dù những lỗi đó đóng góp một số lượng khá, và những khía cạnh đó chắc chắn làm cho tính chính xác của chương trình khó xảy ra hơn nhiều). Tuy nhiên, bạn có thể đưa ra tuyên bố chung chung hơn rằng các nhà toán học thiếu nhiều mối quan tâm của các lập trình viên như hiệu suất, thời gian tiếp thị, khả năng bảo trì và khả năng hạn chế để thay đổi các yêu cầu nếu chúng quá khó khăn.
Derek Elkins

3

Không phải vậy. Bằng chứng toán học chính xác là lỗi, chỉ là độc giả của họ dễ dãi hơn trình biên dịch. Tương tự, các độc giả của một chương trình máy tính dễ bị lừa tin rằng nó là chính xác, ít nhất là cho đến khi họ cố gắng chạy nó.

Ví dụ: nếu chúng tôi cố gắng dịch một bằng chứng toán học sang ngôn ngữ chính thức như ZFC, nó cũng sẽ chứa lỗi. Đó là bởi vì những bằng chứng này có thể trở nên rất dài nên chúng tôi buộc phải viết một chương trình để tạo ra bằng chứng. Rất ít người gặp rắc rối, trong tình trạng nguy hiểm, mặc dù có nghiên cứu tích cực trong việc chính thức hóa các bằng chứng nền tảng.

Và thực sự, toán học có thể có được BSOD! Đây không phải là lần đầu tiên!

nhập mô tả hình ảnh ở đây

Ý tưởng chính thống này cho thấy tất cả các bằng chứng toán học đã được xác minh đầy đủ về cơ bản là chính xác hoặc có thể được thực hiện chính xác là cùng một động lực thúc đẩy dự án phần mềm của bạn tại nơi làm việc: miễn là chúng tôi theo lộ trình, chúng tôi sẽ khắc phục được tất cả các lỗi và tính năng hoàn tất - đó là một quá trình lặp đi lặp lại dẫn đến một sản phẩm cuối cùng xác định.

Đây là mặt trái. Hãy nhìn xem, chúng ta đã có tài trợ, xác nhận khái niệm kinh doanh, tất cả các tài liệu đều ở ngay đây để bạn đọc. Chúng tôi chỉ cần bạn thực hiện và đó là một điều chắc chắn!

Chúng ta cũng không cảm thấy quá tiếc cho Hilbert , anh ta biết mình đang làm gì. Đó chỉ là kinh doanh.

Nếu bạn muốn thực sự chắc chắn, hãy đưa mọi thứ vào từng trường hợp cụ thể và đưa ra kết luận của riêng bạn!


3

Tôi thấy hai lý do quan trọng tại sao các chương trình dễ bị lỗi hơn bằng chứng toán học:

1: Các chương trình chứa các biến hoặc các đối tượng động thay đổi theo thời gian, trong khi các đối tượng toán học trong chứng minh thường tĩnh. Do đó, ký hiệu trong toán học có thể được sử dụng như là sự hỗ trợ trực tiếp cho lý luận, (và nếu a = b, đây vẫn là trường hợp) khi điều này không hoạt động trong các chương trình. Ngoài ra, vấn đề này trở nên tồi tệ hơn nhiều khi các chương trình song song hoặc có nhiều luồng.

2: Toán học thường giả sử các đối tượng được xác định tương đối gọn gàng (đồ thị, đa tạp, vòng, nhóm, v.v.) trong khi lập trình xử lý các đối tượng rất lộn xộn và khá bất thường: số học chính xác hữu hạn, ngăn xếp hữu hạn, chuyển đổi số nguyên, con trỏ, rác cần thu thập , v.v ... Việc thu thập các điều kiện liên quan đến tính chính xác do đó rất khó ghi nhớ.


3

Bạn nên phân biệt hai "danh mục" khác nhau:

  • bằng chứng giả (hoặc mã giả) - đó là những gì bạn thấy trong sách. Nó được viết bằng ngôn ngữ tự nhiên (ví dụ bằng tiếng Anh). Đó là những gì bạn nên sử dụng để học Toán (hoặc Thuật toán).
  • bằng chứng chính thức (hoặc mã chính thức) - bạn viết nó khi bạn cần bằng chứng (hoặc mã) của mình để có thể kiểm chứng về mặt cơ học (hoặc có thể thực thi được). Đại diện như vậy không yêu cầu bất kỳ "trí thông minh của con người". Nó có thể được xác minh (hoặc thực hiện) một cách máy móc, bằng cách làm theo một số bước được xác định trước (thường được thực hiện bởi các máy tính ngày nay).

Chúng tôi đã sử dụng mã giả trong hàng ngàn năm (ví dụ thuật toán Euclids). Viết mã chính thức (bằng các ngôn ngữ chính thức như C hoặc Java) trở nên cực kỳ phổ biến và hữu ích sau khi phát minh ra máy tính. Nhưng, thật đáng buồn, bằng chứng chính thức (bằng các ngôn ngữ chính thức như Princia Mathematica hoặc Metamath) không phổ biến lắm. Và vì mọi người đều viết bằng chứng giả ngày nay, mọi người thường tranh luận về bằng chứng mới. Những sai lầm trong đó có thể được tìm thấy trong nhiều năm, nhiều thập kỷ hoặc thậm chí hàng thế kỷ sau khi "chứng minh" thực sự.


3

Tôi không thể tìm thấy tài liệu tham khảo, nhưng tôi nghĩ Tony Hoare đã từng nói điều gì đó dọc theo các dòng sau: Sự khác biệt giữa kiểm tra chương trình và kiểm tra bằng chứng là bằng chứng có thể được kiểm tra hai dòng cùng một lúc.

Trong một từ: địa phương.

Bằng chứng được viết để có thể dễ dàng kiểm tra. Các chương trình được viết để chúng có thể được thực thi. Vì lý do này, các lập trình viên thường bỏ qua thông tin sẽ hữu ích cho ai đó kiểm tra chương trình.

Hãy xem xét chương trình này, trong đó x là chỉ đọc

    assume x >= 0
    p := 0 ;
    var pp := 0 ;
    while( x >= pp + 2*p + 1 ) 
    {
        var q := 1 ;
        var qq := q ;
        var pq := p ;
        while(  pp + 4*pq + 4*qq <= x )
        {
            q, pq, qq := 2*q, 2*pq, 4*qq ;
        }
        p, pp := p + q, pp + 2*pq + qq ;
    }
    assert  p*p <= x < (p+1)*(p+1)

Nó rất dễ thực hiện, nhưng khó kiểm tra.

Nhưng nếu tôi thêm lại vào các xác nhận bị thiếu, bạn có thể kiểm tra chương trình cục bộ bằng cách kiểm tra xem từng chuỗi bài tập có đúng với việc sửa lại các điều kiện trước và sau của nó hay không, và đối với mỗi vòng lặp, điều kiện hậu của vòng lặp được ngụ ý bởi bất biến và sự phủ định của vòng bảo vệ.

    assume x >= 0
    p := 0 ;
    var pp := 0 ; 
    while( x >= pp + 2*p + 1 ) 
        invariant p*p <= x 
        invariant pp == p*p
        decreases x-p*p 
    {
        var q := 1 ;
        var qq := q ; 
        var pq := p ; 
        while(  pp + 4*pq + 4*qq <= x )
            invariant (p+q)*(p+q) <= x
            invariant q > 0 
            invariant qq == q*q 
            invariant pq == p*q 
            decreases x-(p+q)*(p+q)
        {
            q, pq, qq := 2*q, 2*pq, 4*qq ;
        }
        assert (p+q)*(p+q) <= x and pp==p*p and pq==p*q and qq==q*q and q>0
        p, pp := p + q, pp + 2*pq + qq ;
    }
    assert  p*p <= x < (p+1)*(p+1)

Quay trở lại câu hỏi ban đầu: Tại sao việc viết ra các bằng chứng toán học lại không có lỗi hơn là viết mã máy tính? Vì các bằng chứng được thiết kế để người đọc của họ dễ dàng kiểm tra, chúng dễ dàng được kiểm tra bởi các tác giả của họ và do đó các tác giả cảnh báo có xu hướng không mắc (hoặc ít nhất là giữ) các lỗi logic trong các bằng chứng của họ. Khi chúng tôi lập trình, chúng tôi thường không viết ra lý do mã của chúng tôi là chính xác; kết quả là khó cho cả người đọc và tác giả của một chương trình kiểm tra mã; kết quả là các tác giả mắc lỗi (và sau đó giữ).

Nhưng có hy vọng. Nếu, khi chúng ta viết một chương trình, chúng ta cũng viết ra lý do mà chúng ta nghĩ rằng chương trình đó là chính xác, thì chúng ta có thể kiểm tra mã khi chúng ta viết nó và do đó viết mã lỗi ít hơn. Điều này cũng có lợi ích là những người khác có thể đọc mã của chúng tôi và tự kiểm tra nó.


2

Chúng tôi có thể hỏi liệu khó khăn hơn trong thực tế , hoặc về nguyên tắc , để viết bằng chứng hoặc viết mã.

Trong thực tế, việc chứng minh là khó hơn nhiều so với mã hóa. Rất ít người đã học hai năm toán cấp đại học có thể viết bằng chứng, thậm chí là tầm thường. Trong số những người đã học CS hai năm đại học, có lẽ ít nhất 30% có thể giải được FizzBuzz .

Nhưng về nguyên tắc , có những lý do cơ bản tại sao nó lại khác. Bằng chứng về nguyên tắc, ít nhất có thể được kiểm tra tính chính xác thông qua một quá trình không đòi hỏi phải phán xét hay hiểu bất cứ điều gì. Các chương trình không thể - chúng tôi thậm chí không thể nói, thông qua bất kỳ quy trình quy định nào, liệu chương trình sẽ dừng lại.


3
Hai năm học toán cấp đại học không có nghĩa là hai năm tập trung vào viết bằng chứng (hoặc dành bất kỳ thời gian nào để viết bằng chứng). Điều đó nói rằng, ấn tượng của tôi là thông thường các lớp hình học trung học cơ sở / trung học phổ thông bao gồm các bằng chứng, vì vậy rõ ràng chúng ta có thể mong đợi ngay cả những đứa trẻ 13 tuổi có thể viết các bằng chứng đơn giản với ít hơn một năm học ở trường đề tài. Tính toán đại số từng bước cũng cơ bản là bằng chứng. Tôi nghĩ rằng bạn đang đặt thanh "tầm thường" cho cách lập trình quá thấp và để chứng minh cách quá cao.
Derek Elkins

3
Chúng tôi có thể viết chương trình theo cùng một cách. Bạn có thể tưởng tượng một yêu cầu rằng mọi chức năng / thủ tục bạn viết phải cung cấp một đặc tả chính thức và bằng chứng (trong Coq, nói) rằng nó đáp ứng thông số kỹ thuật. Sau đó, có nhiều cách để kiểm tra bằng chứng đó cho chính xác theo cách không đòi hỏi phải phán xét hay hiểu gì.
DW

@DW: Bạn đang giả định rằng (1) hành vi mong muốn có thể được chỉ định đầy đủ trong mọi trường hợp, (2) bằng chứng cần thiết tồn tại (nghĩa là vấn đề không phải là không thể giải quyết được) và (3) nếu bằng chứng tồn tại, thì chúng tôi có thể tìm thấy nó Tôi nghĩ rằng cả ba giả định này đều sai trong ít nhất một số trường hợp (có thể gần như tất cả các trường hợp). Re 3, lưu ý rằng mặc dù một số bằng chứng có thể dễ dàng, nhiều bằng chứng rất khó tìm.
Ben Crowell

@DerekElkins: Yêu cầu của tôi rằng rất ít sinh viên đại học có thể viết bằng chứng thậm chí tầm thường dựa trên kinh nghiệm của riêng tôi với các sinh viên của mình. Đây là tại một trường cao đẳng cộng đồng, vì vậy YMMV. Thực tế là một số lớp hình học ở trường trung học bao gồm một lượng lớn bằng văn bản chứng minh không chuyển thành thực tế là tất cả các sinh viên đại học có thể viết bằng chứng. Họ cũng được cho là biết cách làm đại số cơ bản, nhưng ở trường tôi, khoảng một nửa số sinh viên calc năm nhất không thể - điều này giúp giải thích tại sao rất nhiều người thất bại.
Ben Crowell

Đó sẽ là một lời giải thích tốt để thêm vào câu trả lời, để giải thích lý do tại sao bạn không thể thực hiện cùng một cách tiếp cận để kiểm tra tính chính xác của chương trình. Nói chung (2) và (3) hiếm khi là một vấn đề, trong thực tế hoặc về nguyên tắc (nếu bạn không thể chứng minh chương trình đúng, hãy viết theo một cách khác cho đến khi bạn có thể chứng minh nó đúng). Tuy nhiên (1) của bạn một điểm quan trọng và tôi nghĩ rằng nó sẽ củng cố câu trả lời để giải thích lý do tại sao điều đó làm cho việc thực hiện điều tương tự đối với các chương trình như chúng tôi làm bằng chứng là khó khăn.
DW

2

Chỉ một phần nhỏ của các báo cáo toán học là đúng có thể được chứng minh thực tế. Quan trọng hơn, không thể xây dựng một tập hợp các tiên đề toán học không tầm thường (*) cho phép tất cả các phát biểu đúng được chứng minh. Nếu người ta chỉ cần viết chương trình để thực hiện một phần rất nhỏ những việc có thể làm với máy tính, thì có thể viết phần mềm có thể chứng minh được, nhưng máy tính thường được yêu cầu làm những việc vượt quá phạm vi của những gì có thể chứng minh được phần mềm có thể thực hiện.

(*) Có thể định nghĩa một tập hợp tiên đề cho phép liệt kê tất cả các câu đúng, và do đó đã được chứng minh, nhưng những điều đó thường không thú vị lắm. Mặc dù có thể chính thức phân loại các tập hợp tiên đề thành các tiên đề hay không, nói một cách tương đối, không tầm thường, điểm mấu chốt là sự tồn tại có thể chứng minh của các tuyên bố là đúng nhưng không thể chứng minh được không phải là một lỗ hổng trong một tập hợp của tiên đề. Việc thêm các tiên đề để làm cho bất kỳ tuyên bố đúng nhưng không thể chứng minh hiện có nào có thể chứng minh được sẽ khiến các tuyên bố khác trở thành đúng nhưng không có chúng có thể chứng minh được.


1
"Chỉ một phần nhỏ của các báo cáo toán học là đúng có thể được chứng minh thực tế." - Bạn đang đo "phần" như thế nào? Đây có phải là dưới một số phân phối xác suất? Bạn có bằng chứng để hỗ trợ tuyên bố này?
DW

"máy tính thường được yêu cầu thực hiện những việc vượt ra ngoài phạm vi của những gì phần mềm có thể chứng minh chính xác có thể thực hiện được." - Bạn có bằng chứng nào cho việc này không? Bạn có một ví dụ? Bạn đang tuyên bố "vượt quá những gì về nguyên tắc có thể được chứng minh là đúng" hay "vượt quá những gì chúng ta có thể tưởng tượng một cách hợp lý chứng minh trong thực tế"?
DW

@DW: Nếu X và Y là các phát biểu trực giao là đúng nhưng không thể chứng minh được thì đối với mọi tuyên bố có thể chứng minh được P, sẽ có ít nhất hai phát biểu trực giao (P và X) và (P và Y) đúng nhưng không -có thể cung cấp. Khi xử lý các tập hợp vô hạn, logic như vậy không nhất thiết phải chứng minh bất cứ điều gì, vì người ta có thể sử dụng logic tương tự để chỉ ra rằng có số nguyên gấp đôi số nguyên so với số nguyên lẻ, vì với mỗi số nguyên lẻ, người ta có thể xác định hai số nguyên chẵn (4x) và (4x + 2) không liên quan đến bất kỳ số nguyên lẻ nào khác, nhưng tất nhiên số nguyên chẵn và số lẻ có số lượng bằng nhau.
supercat

@DW: Cụm từ "phần nhỏ" có thể chỉ thực sự có ý nghĩa trong việc mô tả phần nhỏ của các tuyên bố thực sự có thể được chứng minh trên thực tế, nhưng tôi nghĩ rằng thật hữu ích khi hiểu rằng việc không thể chứng minh tất cả các tuyên bố đúng không phải là một "lỗ hổng". Đối với máy tính, nhiều trường thường xuyên sử dụng các thuật toán có xác suất thất bại rất nhỏ, nhưng khác không, và sau đó điều chỉnh chúng sao cho xác suất đó thấp đến mức có thể chấp nhận được (ví dụ: dưới mức thiết bị bị thiên thạch tấn công). Tuy nhiên, trong nhiều trường hợp, các chế độ thất bại khác nhau không độc lập, tuy nhiên, về cơ bản có thể là không thể ...
supercat

... Để xác định xác suất của các kết hợp thất bại khác nhau. Nếu người ta ước tính xác suất thất bại trong khoảng thời gian một phút tùy ý là một trong 10 ^ -500, thì người ta có thể tắt hàng trăm đơn đặt hàng cường độ và vẫn có một hệ thống đáng tin cậy, nhưng nếu một trong số đó bị giảm 494 đơn hàng cường độ hệ thống sẽ thất bại khoảng một vài năm một lần.
supercat

2
  1. Các chương trình máy tính được thử nghiệm trong thế giới thực. Một lỗi kỹ thuật khó khăn trong một bằng chứng toán học dài, mà chỉ một số người hạn chế có thể hiểu, có cơ hội tốt mà không bị phát hiện. Loại lỗi tương tự trong một sản phẩm phần mềm có khả năng tạo ra hành vi lạ mà người dùng thông thường nhận thấy. Vì vậy, tiền đề có thể không chính xác.

  2. Các chương trình máy tính thực hiện các chức năng thực tế hữu ích. Họ không cần phải đúng 100% để làm điều này và các tiêu chuẩn chính xác cao là khá tốn kém. Bằng chứng chỉ hữu ích nếu chúng thực sự chứng minh điều gì đó, vì vậy bỏ qua phần 'đúng 100%' không phải là một lựa chọn cho các nhà toán học.

  3. Chứng minh toán học được xác định rõ ràng. Nếu một bằng chứng là thiếu sót, tác giả đã phạm sai lầm. Nhiều lỗi trong các chương trình máy tính xảy ra do các yêu cầu không được truyền đạt chính xác hoặc có vấn đề tương thích với thứ mà lập trình viên chưa bao giờ nghe thấy.

  4. Nhiều chương trình máy tính không thể được chứng minh là đúng. Họ có thể giải quyết các vấn đề được xác định không chính thức như nhận diện khuôn mặt. Hoặc chúng có thể giống như phần mềm dự đoán thị trường chứng khoán và có một mục tiêu được xác định chính thức nhưng liên quan đến quá nhiều biến số trong thế giới thực.


2

Một phần lớn toán học là một hoạt động của con người là sự phát triển của các ngôn ngữ cụ thể theo miền, trong đó việc xác minh bằng chứng là dễ dàng đối với con người.

Chất lượng của một bằng chứng tỷ lệ nghịch với độ dài và độ phức tạp của nó. Độ dài và độ phức tạp thường được giảm bằng cách phát triển ký hiệu tốt để mô tả tình huống hiện tại mà chúng tôi đang đưa ra tuyên bố, cùng với các khái niệm phụ trợ tương tác trong bằng chứng cụ thể đang được xem xét.

Đây không phải là một quá trình dễ dàng và hầu hết các bằng chứng được chứng kiến ​​bởi những người bị loại bỏ khỏi nghiên cứu hàng đầu đều xảy ra trong các lĩnh vực toán học (như đại số và phân tích) đã có hàng trăm, nếu không phải hàng ngàn năm, trong đó ký hiệu của lĩnh vực đó đã có đã được tinh chỉnh đến mức mà hành động thực sự viết ra các bằng chứng cảm thấy như một làn gió.

Mặc dù đi đầu trong nghiên cứu, đặc biệt nếu bạn làm việc với các vấn đề không thuộc các lĩnh vực có ký hiệu được thiết lập tốt hoặc phát triển tốt, tôi sẽ đặt ra khó khăn trong việc viết một bằng chứng chính xác tiếp cận khó khăn trong việc viết một chương trình chính xác. Điều này có thể là do bạn cũng phải đồng thời viết tương tự thiết kế ngôn ngữ lập trình, huấn luyện mạng thần kinh của bạn để biên dịch chính xác, thử viết bằng chứng trong đó, hết bộ nhớ, cố gắng tối ưu hóa ngôn ngữ, lặp đi lặp lại bộ não của bạn học ngôn ngữ, viết lại bằng chứng, vv

Để nhắc lại, tôi nghĩ rằng việc viết bằng chứng chính xác có thể gặp khó khăn khi viết chương trình đúng trong một số lĩnh vực nhất định của toán học, nhưng những lĩnh vực đó nhất thiết phải còn non trẻ và kém phát triển bởi vì khái niệm tiến bộ trong toán học gắn liền với sự dễ chứng minh xác minh.

Một cách khác để diễn đạt điểm tôi muốn đưa ra là cả ngôn ngữ lập trình và toán học đều được thiết kế để các chương trình máy tính và bằng chứng tương ứng có thể biên dịch. Chỉ là việc biên dịch một chương trình máy tính được thực hiện trong máy tính và đảm bảo tính chính xác cú pháp thường không liên quan đến tính chính xác của chương trình, trong khi "biên dịch" một bằng chứng được thực hiện bởi con người và đảm bảo tính chính xác về cú pháp giống như tính đúng đắn của bằng chứng.


1

Bạn đang thành thật so sánh táo và cam ở đây. Chống lỗi và không có lỗi không giống nhau.

Nếu một chương trình so sánh các con số 23nó nói điều đó 2 is greater than 3, thì đó có thể là do triển khai lỗi:

# Buggy implementation
function is_a_greater_than_b(a,b):
  return b > a

Chương trình vẫn không có lỗi mặc dù. Khi so sánh hai số ab, nó sẽ luôn có thể cho bạn biết nếu blớn hơn số a. Đó không phải là những gì bạn (lập trình viên) phải yêu cầu máy tính làm.


2
Định nghĩa của bạn về "lỗi" trong một chương trình là gì?
dùng56834

0

a) Bởi vì các chương trình máy tính lớn hơn bằng chứng toán học

a.1) Tôi tin rằng có nhiều người được sử dụng trong khi viết chương trình máy tính phức tạp hơn là trong khi viết bằng chứng toán học. Nó có nghĩa là biên sai lầm cao hơn.

b) Vì CEO / Cổ đông quan tâm đến tiền nhiều hơn là sửa các lỗi nhỏ , trong khi đó, bạn (với tư cách là nhà phát triển) phải thực hiện các nhiệm vụ của mình để đáp ứng một số yêu cầu / thời hạn / bản demo

c) Bởi vì bạn có thể là lập trình viên mà không có kiến ​​thức "sâu" về comp sci, trong khi đó, thật khó để làm toán (tôi tin)

Ngoài ra:

NASA:

Phần mềm này không có lỗi. Nó là hoàn hảo, hoàn hảo như con người đã đạt được. Hãy xem xét các số liệu thống kê này: ba phiên bản cuối cùng của chương trình - mỗi phiên bản dài 420.000 dòng - chỉ có một lỗi. 11 phiên bản cuối cùng của phần mềm này có tổng cộng 17 lỗi.

Hãy nâng cấp phần mềm để cho phép tàu con thoi điều hướng với Vệ tinh định vị toàn cầu, một thay đổi chỉ liên quan đến 1,5% chương trình, hoặc 6.366 dòng mã. Các thông số kỹ thuật cho một thay đổi đó chạy 2.500 trang, dày hơn một cuốn sách điện thoại. Các thông số kỹ thuật cho chương trình hiện tại điền 30 tập và chạy 40.000 trang.

https://www.fastcompany.com/28121/they-write-right- ware


"Các chương trình máy tính là waaay lớn hơn bằng chứng toán học" Điều đó phụ thuộc vào chương trình và bằng chứng. Và phần lớn điều này dường như là rất đầu cơ.
David Richerby

@DavidR Richby Tôi đã có ý tưởng về những thứ như Định lý của fermat cuối cùng và Apollo github.com/chrislgarry/Apollo-11 math.wisc.edu/~boston/869.pdf - và chúng tôi thậm chí không nói về các hệ điều hành, v.v.
Exeus

0

Cấp độ cơ bản:

Chúng ta hãy nhìn vào mọi thứ ở mức độ đơn giản nhất và cơ bản nhất.

Đối với môn toán, ta có:
2 + 3 = 5

Tôi đã học về điều đó khi tôi còn rất, rất trẻ. Tôi có thể nhìn vào các yếu tố cơ bản nhất: hai đối tượng và ba đối tượng. Tuyệt quá.

Đối với lập trình máy tính, hầu hết mọi người có xu hướng sử dụng ngôn ngữ cấp cao. Một số ngôn ngữ cấp cao thậm chí có thể "biên dịch" thành một trong những ngôn ngữ cấp cao thấp hơn, như C. C sau đó có thể được dịch sang ngôn ngữ hội. Ngôn ngữ hội sau đó được chuyển đổi thành mã máy. Nhiều người nghĩ rằng sự phức tạp kết thúc ở đó, nhưng nó không: CPU hiện đại lấy mã máy làm hướng dẫn, nhưng sau đó chạy "micro code" để thực sự thực hiện các hướng dẫn đó.

Điều này có nghĩa là, ở cấp độ cơ bản nhất (xử lý các cấu trúc đơn giản nhất), chúng ta hiện đang xử lý mã vi mô, được nhúng trong phần cứng và hầu hết các lập trình viên thậm chí không sử dụng trực tiếp, cũng không cập nhật. Trên thực tế, không chỉ hầu hết các lập trình viên không chạm vào mã vi (cao hơn 0 cấp so với mã vi), hầu hết các lập trình viên không chạm vào mã máy (cao hơn 1 cấp so với mã vi), thậm chí không lắp ráp (cao hơn 2 cấp so với mã vi) ( ngoại trừ, có lẽ, cho một chút đào tạo chính thức trong thời gian học đại học). Hầu hết các lập trình viên sẽ dành thời gian chỉ cao hơn 3 cấp.

Hơn nữa, nếu chúng ta nhìn vào hội (mức độ thấp như mọi người thường nhận được), mỗi bước riêng lẻ thường được hiểu bởi những người đã được đào tạo và có tài nguyên để diễn giải bước đó. Theo nghĩa này, hội đơn giản hơn nhiều so với ngôn ngữ cấp cao hơn. Tuy nhiên, hội đơn giản đến mức thực hiện các nhiệm vụ phức tạp, hoặc thậm chí là các nhiệm vụ tầm thường, rất tẻ nhạt. Ngôn ngữ cấp trên giải phóng chúng ta khỏi điều đó.

Trong một luật về "kỹ thuật đảo ngược", một thẩm phán tuyên bố rằng ngay cả khi về mặt lý thuyết mã có thể được xử lý một byte một lần, các chương trình hiện đại liên quan đến hàng triệu byte, do đó, một số loại bản ghi (như bản sao mã) phải được tạo ra như vậy một nỗ lực để được khả thi. (Do đó, phát triển nội bộ không được coi là vi phạm quy tắc luật bản quyền "không tạo bản sao".) (Có lẽ tôi đang nghĩ đến việc tạo ra các hộp mực Sega Genesis trái phép, nhưng có thể đang nghĩ về điều gì đó được nói trong vụ kiện Game Genie. )

Hiện đại hóa:

Bạn có chạy mã có nghĩa là cho 286s? Hay bạn chạy mã 64 bit?

Toán học sử dụng các nguyên tắc cơ bản kéo dài hàng thiên niên kỷ. Với máy tính, mọi người thường coi đầu tư vào thứ gì đó hai thập kỷ là lãng phí tài nguyên vô ích. Điều đó có nghĩa là Toán học có thể được kiểm tra kỹ lưỡng hơn rất nhiều.

Tiêu chuẩn của các công cụ được sử dụng:

Tôi đã được dạy (bởi một người bạn đã đào tạo lập trình máy tính chính thức hơn tôi) rằng không có trình biên dịch C không có lỗi nào đáp ứng các thông số kỹ thuật C. Điều này là do ngôn ngữ C về cơ bản đảm nhận khả năng sử dụng bộ nhớ vô hạn cho mục đích ngăn xếp. Rõ ràng, một yêu cầu bất khả thi như vậy phải được đưa ra từ khi mọi người cố gắng tạo ra các trình biên dịch có thể sử dụng được làm việc với các máy thực tế có bản chất hữu hạn hơn một chút.

Trong thực tế, tôi đã thấy rằng với JScript trong Windows Script Host, tôi đã có thể hoàn thành rất nhiều đối tượng sử dụng tốt. (Tôi thích môi trường vì bộ công cụ cần dùng thử mã mới được tích hợp vào các phiên bản hiện đại của Microsoft Windows.) Khi sử dụng môi trường này, tôi thấy rằng đôi khi không có tài liệu nào dễ tìm thấy về cách thức hoạt động của đối tượng. Tuy nhiên, sử dụng đối tượng là rất có lợi, dù sao tôi cũng làm như vậy. Vì vậy, những gì tôi sẽ làm là viết mã, có thể là lỗi như một tổ ong bắp cày và làm như vậy trong một môi trường hộp cát độc đáo nơi tôi có thể nhìn thấy các hiệu ứng và tìm hiểu về hành vi của đối tượng trong khi tương tác với nó.

Trong các trường hợp khác, đôi khi chỉ sau khi tôi phát hiện ra một đối tượng hoạt động như thế nào, tôi mới thấy rằng đối tượng (đi kèm với hệ điều hành) có lỗi và đó là một vấn đề đã biết mà Microsoft đã cố tình quyết định sẽ không được khắc phục .

Trong các kịch bản như vậy, tôi có dựa vào OpenBSD, được tạo bởi các lập trình viên bậc thầy tạo ra các bản phát hành mới theo lịch, thường xuyên (hai lần một năm), với một hồ sơ bảo mật nổi tiếng "chỉ có hai lỗ hổng từ xa" trong hơn 10 năm không? (Ngay cả họ cũng có các bản vá errata cho các vấn đề ít nghiêm trọng hơn.) Không, không có nghĩa là. Tôi không dựa vào một sản phẩm có chất lượng cao như vậy, bởi vì tôi đang làm việc cho một doanh nghiệp hỗ trợ các doanh nghiệp cung cấp cho mọi người máy sử dụng Microsoft Windows, vì vậy đó là điều mà mã của tôi cần phải hoạt động.

Tính thực tiễn / khả năng sử dụng yêu cầu tôi làm việc trên các nền tảng mà mọi người thấy hữu ích và đó là một nền tảng nổi tiếng về bảo mật (mặc dù những cải tiến to lớn đã được thực hiện từ những ngày đầu của thiên niên kỷ mà các sản phẩm của cùng một công ty tệ hơn nhiều) .

Tóm lược

Có nhiều lý do tại sao lập trình máy tính dễ bị lỗi hơn và được cộng đồng người dùng máy tính chấp nhận. Trong thực tế, hầu hết các mã được viết trong các môi trường sẽ không chấp nhận các nỗ lực không có lỗi. (Một số trường hợp ngoại lệ, chẳng hạn như phát triển các giao thức bảo mật, có thể nhận được một chút nỗ lực hơn về vấn đề này.) Bên cạnh những suy nghĩ thường thấy về lý do các doanh nghiệp không muốn đầu tư nhiều tiền hơn và bỏ lỡ thời hạn nhân tạo để làm cho khách hàng hài lòng, có tác động của sự tiến bộ của công nghệ chỉ đơn giản là nếu bạn dành quá nhiều thời gian, bạn sẽ làm việc trên một nền tảng lỗi thời bởi vì mọi thứ thay đổi đáng kể trong vòng một thập kỷ.

Chính thức, tôi có thể nhớ lại đã rất ngạc nhiên khi thấy một số hàm rất hữu ích và phổ biến ngắn đến mức nào, khi tôi thấy một số mã nguồn cho strlen và strcpy. Chẳng hạn, strlen có thể là một cái gì đó như "int strlen (char * x) {char y = x; while ( (y ++)); return (yx) -1;}"

Tuy nhiên, các chương trình máy tính thông thường dài hơn thế nhiều. Ngoài ra, rất nhiều chương trình hiện đại sẽ sử dụng mã khác có thể được kiểm tra ít kỹ lưỡng hơn, hoặc thậm chí được biết là có lỗi. Các hệ thống ngày nay phức tạp hơn nhiều so với những gì có thể dễ dàng nghĩ ra, ngoại trừ bằng cách vẫy tay rất nhiều chi tiết vụn vặt như "chi tiết được xử lý bởi các cấp thấp hơn".

Sự phức tạp bắt buộc này, và sự chắc chắn khi làm việc với các hệ thống phức tạp và thậm chí sai, khiến lập trình máy tính trở thành phần cứng rất nhiều để xác minh hơn rất nhiều toán học, nơi mọi thứ có xu hướng sôi sục đến mức đơn giản hơn rất nhiều.

Khi bạn phá vỡ mọi thứ trong toán học, bạn có được những mảnh riêng lẻ mà trẻ có thể hiểu được. Hầu hết mọi người tin tưởng toán học; ít nhất là số học cơ bản (hoặc, ít nhất là, tính).

Khi bạn thực sự phá vỡ chương trình máy tính để xem những gì đang diễn ra, bạn sẽ gặp phải việc triển khai các tiêu chuẩn và mã bị hỏng cuối cùng được thực thi bằng điện tử, và việc triển khai vật lý chỉ là một bước so với vi mã mà hầu hết các nhà khoa học máy tính được đào tạo đại học Sẽ không dám chạm vào (nếu họ thậm chí còn biết về nó).

Tôi đã nói chuyện với một số lập trình viên đang học đại học hoặc những sinh viên tốt nghiệp gần đây, những người hoàn toàn phản đối quan niệm rằng mã không có lỗi có thể được viết. Họ đã viết ra khả năng này và mặc dù họ thừa nhận rằng một số ví dụ ấn tượng (mà tôi đã có thể đưa ra) là một số lập luận thuyết phục, họ coi những mẫu đó là những con sáo hiếm có thể biểu hiện được, và vẫn bác bỏ khả năng có thể đếm được về việc có các tiêu chuẩn cao hơn như vậy. (Một thái độ rất, khác nhiều so với nền tảng đáng tin cậy hơn nhiều mà chúng ta thấy trong toán học.)


1
Trong khi bạn tạo ra một trường hợp tốt đẹp cho sự phức tạp của lập trình, bạn hầu như không xem xét toán học chút nào! Trên thực tế, bạn dường như đánh giá thấp sự phức tạp liên quan đến toán học chính thức: "Khi bạn phá vỡ mọi thứ trong toán học, bạn có thể tìm ra những mảnh riêng lẻ mà trẻ em có thể hiểu được", thực sự ? Bên cạnh đó, điều tương tự cũng có thể nói về lập trình 'cấp cao' đủ (ví dụ: Scratch được thiết kế cho trẻ em). Cũng lưu ý rằng Mặc dù thông số C đầy đủ không thể thực hiện được, một trình biên dịch hỗ trợ một tập hợp con quan trọng đã được hiển thị chính xác bằng các bằng chứng hỗ trợ máy tính.
Thằn lằn rời rạc

2+3=5

Meta lưu ý: nếu bạn là một chuyên gia về một điều và một người mới bắt đầu chuyên gia (hoặc thấp hơn) trong một điều khác, bạn đang ở vị trí tồi tệ nhất có thể để so sánh hai điều này.
Raphael

Thằn lằn rời rạc - đây là Khoa học Máy tính SE. Hơn nữa, thực sự đã đọc các câu trả lời khác trước khi tôi đăng, tôi cảm thấy như họ chạm vào toán học nhiều hơn máy tính. Tôi cảm thấy câu trả lời của mình tốt hơn bằng cách không làm cho nó dài hơn chỉ để thêm những từ mà phần lớn là dư thừa với những gì được viết ở nơi khác. /// Đối với Scratch, mức độ cao phức tạp hơn, không đơn giản hơn (khi nhìn vào quan điểm hiểu đầy đủ tất cả các bộ phận chuyển động). Theo quan điểm này, mà tôi đã viết từ đó, hội đơn giản hơn Scratch trên đầu các lớp khác (với cổng NAND điện tử đơn giản hơn)
QUÁN NGÀY

0

Bằng chứng toán học mô tả "những gì" kiến ​​thức và chương trình mô tả "làm thế nào để" kiến ​​thức ".

Viết chương trình phức tạp hơn vì lập trình viên phải suy luận về tất cả các trạng thái khác nhau có thể phát sinh và kết quả là hành vi của chương trình thay đổi như thế nào. Bằng chứng sử dụng lý luận công thức hoặc phân loại để chứng minh những điều về các định nghĩa khác.

Hầu hết các lỗi được gây ra bởi các quá trình đi vào trạng thái mà lập trình viên không lường trước được. Trong một chương trình, bạn thường có hàng ngàn hoặc, trong một hệ thống lớn, hàng triệu biến có thể không phải là dữ liệu tĩnh, nhưng thực sự biến đổi cách thức thực hiện chương trình. Tất cả những thứ này tương tác với nhau tạo ra những hành vi không thể lường trước được, đặc biệt là trong một máy tính hiện đại, nơi có những lớp trừu tượng thay đổi bên dưới bạn.

Trong một bằng chứng, không có trạng thái thay đổi. Các định nghĩa và đối tượng thảo luận là cố định. Chứng minh không đòi hỏi phải suy nghĩ về vấn đề nói chung và xem xét rất nhiều trường hợp, nhưng những trường hợp đó được cố định bởi các định nghĩa.


2
Tôi muốn nói rằng các bằng chứng toán học hoàn toàn có khả năng mô tả kiến ​​thức 'cái gì': lấy ví dụ như bất kỳ bằng chứng nào xây dựng một ví dụ để chứng minh sự tồn tại hoặc một phương pháp để tính toán một giá trị. Tuy nhiên, tôi đồng ý rằng trạng thái là một cái gì đó vắng mặt trong các bằng chứng, theo nghĩa là không có trạng thái nào khác ngoài trạng thái được mô tả rõ ràng bởi tác giả (hoặc người đọc!). Chính xác là trạng thái này cho phép một chương trình làm điều gì đó mà người đọc / tác giả không biết, trong khi điều này là không thể trong một bằng chứng. (chắc chắn, bằng chứng có thể có các tính năng hoặc kết quả ngoài ý muốn, nhưng vẫn còn một số suy nghĩ tích cực cần có để có được chúng)
Thằn lằn rời rạc

@Discretelizard Đây là một nhận xét hữu ích. Tôi nghĩ ranh giới giữa "cái gì" và "làm thế nào" chắc chắn là mờ nhạt. Chứng minh một thuật toán thực hiện những gì bạn nghĩ, thực sự không mô tả "làm thế nào" trong tâm trí của tôi, nó chỉ đảm bảo các thuộc tính nhất định giữ. Từ quan điểm triết học, tôi nghĩ kiến ​​thức "làm thế nào" đòi hỏi phải có sự tương ứng với thế giới. Các chương trình luôn làm những gì bạn nói với họ. Khi bạn gặp lỗi, những gì bạn bảo nó không tương ứng với thế giới (những gì bạn đang làm mô hình). Toán học, độc lập với một ứng dụng (như các vấn đề vật lý) dường như đều phụ thuộc vào sự gắn kết.
Justin Meiners
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.