การพิสูจน์ความถูกต้องของรหัสจะเป็นเรื่องสำคัญหรือไม่ [ปิด]


14

ทั้งหมดยกเว้นโปรแกรมที่น่ารำคาญที่สุดเต็มไปด้วยข้อบกพร่องและดังนั้นสิ่งที่สัญญาว่าจะลบออกนั้นมีเสน่ห์อย่างมาก ในขณะนี้การพิสูจน์ความถูกต้องเป็นรหัสมีความลับอย่างมากส่วนใหญ่เป็นเพราะการเรียนรู้อย่างยากลำบากและความพยายามพิเศษที่ใช้ในการพิสูจน์โปรแกรมที่ถูกต้อง คุณคิดว่าการพิสูจน์โค้ดนั้นจะเกิดขึ้นไหม?

คำตอบ:


8

ไม่ใช่ในแง่นั้นจริงๆ แต่การเขียนโปรแกรมฟังก์ชั่นที่บริสุทธิ์นั้นดีในโดเมนนี้ หากคุณใช้ Haskell อาจเป็นไปได้ว่าโปรแกรมของคุณถูกต้องหากรหัสรวบรวม ยกเว้นจาก IO ระบบชนิดที่ดีคือความช่วยเหลือที่ดี

นอกจากนี้การเขียนโปรแกรมไปยังสัญญาจะเป็นประโยชน์ ดูสัญญารหัสของ Microsoft


6
ขออภัยฉันไม่ได้ทำ Haskell "โลกแห่งความจริง" มากนัก แต่ฉันได้ทำแบบฝึกหัดการสอนที่เพียงพอสำหรับอายุการใช้งานหลายครั้ง เพียงเพราะมันรวบรวมไม่ได้หมายความว่ามันมีแนวโน้มที่จะทำงาน เปรียบเทียบกับเช่น Ada (เลือกเพราะมันเป็นภาษาที่จำเป็นอย่างยิ่งในการพิมพ์แบบคงที่) ฉันว่า Haskell นั้นง่ายกว่าเล็กน้อย แต่ส่วนใหญ่เป็นเพราะมันกระชับกว่า เมื่อต้องรับมือกับ IO monad มีสิ่งที่น่ารำคาญที่ทำให้ Haskell ยากขึ้น - มันแตกต่างจากรูปแบบที่จำเป็นซึ่งมีสิ่งที่ไม่สามารถทำได้ตามธรรมชาติ
Steve314

ใน "ไม่สามารถทำได้ตามปกติ" ให้พิจารณาการวนรอบแบบ "ขณะ" ใช่คุณสามารถหมุนของคุณเอง - แต่เงื่อนไข while ต้องอยู่ภายใน monad เพราะต้องการการตอบสนองต่อผลข้างเคียงของตัวลูป ไม่เพียงหมายความว่าคุณได้รับอนุญาตให้ทำให้เกิดผลข้างเคียงในเงื่อนไข while แต่ยังทำให้ใช้อึดในขณะที่วนซ้ำได้ ผลลัพธ์สุดท้าย - โดยทั่วไปจะใช้การเรียกซ้ำได้ง่ายขึ้นแม้ในรหัส IO monad - และนั่นหมายความว่าคุณต้องจัดโครงสร้างสิ่งต่าง ๆ ด้วยวิธีเฉพาะ
Steve314

14

ทั้งหมดยกเว้นรายการเล็กน้อยที่สุด

ไม่สามารถพิสูจน์ได้อย่างสมบูรณ์ว่าถูกต้องด้วยความพยายามตามสมควร สำหรับการพิสูจน์ความถูกต้องอย่างเป็นทางการคุณต้องมีสเป็คอย่างเป็นทางการอย่างน้อยและสเป็คนั้นต้องสมบูรณ์และถูกต้อง นี่คือสิ่งที่คุณไม่สามารถสร้างได้ง่ายสำหรับโปรแกรมที่ใช้งานจริงส่วนใหญ่ ตัวอย่างเช่นลองเขียนข้อมูลจำเพาะสำหรับสิ่งที่ต้องการอินเทอร์เฟซผู้ใช้ของไซต์การสนทนานี้และคุณรู้ว่าฉันหมายถึงอะไร

ที่นี่ฉันพบบทความที่ดีในหัวข้อ:

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


ถูกต้อง - สำหรับโครงการการเขียนโปรแกรมใด ๆ จะมีการเปลี่ยนจากคำอธิบายอย่างไม่เป็นทางการของปัญหาไปเป็นทางการ (โดยทั่วไปวันนี้ในรูปแบบของโปรแกรม) และนั่นจะไม่หายไป
David Thornley

astree.ens.frดูการใช้งานทางอุตสาหกรรมของAstréeที่นี่
zw324

@ZiyaoWei: เครื่องมือดังกล่าวมีประโยชน์ แต่พวกเขาพบข้อผิดพลาดที่เป็นทางการไม่มาก หากโปรแกรมหนึ่งบรรทัดเช่นprintf("1")ถูกต้องหรือไม่ (ตัวอย่างเช่นเนื่องจากข้อกำหนดคือ "พิมพ์ตัวเลขสุ่มที่กระจายแบบเท่า ๆ กันจาก 1 ถึง 6") ไม่สามารถตัดสินใจได้โดยตัววิเคราะห์แบบคงที่
Doc Brown

10

ปัญหาเกี่ยวกับการพิสูจน์อย่างเป็นทางการก็คือมันจะย้ายปัญหากลับขั้นตอน

การบอกว่าโปรแกรมนั้นถูกต้องเทียบเท่ากับการบอกว่าโปรแกรมทำในสิ่งที่ควรทำ คุณจะกำหนดสิ่งที่โปรแกรมควรทำอย่างไร คุณระบุมัน และคุณจะกำหนดว่าโปรแกรมควรทำอย่างไรในกรณีขอบที่สเป็คไม่ครอบคลุม? งั้นคุณต้องทำให้สเป็คมีรายละเอียดมากขึ้น

สมมุติว่าสเป็คของคุณมีรายละเอียดเพียงพอที่จะอธิบายพฤติกรรมที่ถูกต้องของทุกแง่มุมของโปรแกรมทั้งหมด ตอนนี้คุณต้องการวิธีที่จะทำให้เครื่องมือพิสูจน์ของคุณเข้าใจ ดังนั้นคุณต้องแปลสเป็คเป็นภาษาทางการบางอย่างที่เครื่องมือพิสูจน์เข้าใจได้ ... เฮ้รอสักครู่!


2
นอกจากนี้ .. "ระวังข้อผิดพลาดในโค้ดด้านบน; ฉันได้พิสูจน์แล้วว่าถูกต้องเท่านั้น, ไม่ได้ทดลองใช้" - Donald Knuth
Brendan

8

การตรวจสอบอย่างเป็นทางการมาไกล แต่โดยปกติแล้วเครื่องมือในอุตสาหกรรม / ที่ใช้กันอย่างแพร่หลายจะล้าหลังการวิจัยล่าสุด นี่คือความพยายามล่าสุดในทิศทางนี้:

Spec # http://research.microsoft.com/en-us/projects/specsharp/ นี่คือส่วนขยายของ C # ที่รองรับสัญญาโค้ด (เงื่อนไขก่อน / หลังและผู้แปรปรวน) และสามารถใช้สัญญาเหล่านี้เพื่อทำการวิเคราะห์แบบคงที่ประเภทต่างๆ .

โครงการที่คล้ายกันนี้มีอยู่สำหรับภาษาอื่นเช่น JML สำหรับ java และ Eiffel มีสิ่งนี้ในตัว

จะยิ่งโครงการเช่นสแลมและระเบิดสามารถนำมาใช้ในการตรวจสอบคุณสมบัติพฤติกรรมบางอย่างกับโปรแกรมเมอร์น้อยที่สุดคำอธิบายประกอบ / แทรกแซง แต่ก็ยังไม่สามารถจัดการกับทั่วไปเต็มรูปแบบของภาษาสมัยใหม่ (สิ่งที่ต้องการจำนวนเต็มล้น / คำนวณตัวชี้ยังไม่ได้สร้างแบบจำลอง)

ฉันเชื่อว่าเราจะเห็นเทคนิคเหล่านี้มากขึ้นที่ใช้ในการฝึกฝนในอนาคต อุปสรรคหลักคือค่าคงที่ของโปรแกรมนั้นยากที่จะอนุมานโดยไม่มีการเพิ่มความคิดเห็นด้วยตนเองและโปรแกรมเมอร์มักไม่เต็มใจที่จะให้คำอธิบายประกอบเหล่านี้เพราะการทำเช่นนั้นน่าเบื่อ / ใช้เวลานานเกินไป


4

ไม่เว้นแต่จะมีวิธีการพิสูจน์โค้ดโดยอัตโนมัติโดยไม่มีงานของนักพัฒนาซอฟต์แวร์เกิดขึ้น


พิจารณาข้อถกเถียงทางเศรษฐกิจ: อาจเป็นการดีกว่าสำหรับนักพัฒนาที่จะ "เสียเวลา" ด้วยการพิสูจน์ความถูกต้องมากกว่าเสียเงินเนื่องจากข้อผิดพลาดของซอฟต์แวร์
Andres F.

ฉันเห็นด้วยกับ fishtoaster เว้นแต่ว่ามันจะกลายเป็นทรัพยากรที่น้อยลงอย่างมากซอฟต์แวร์ธุรกิจปกติจำนวนมากก็ไม่ได้มีค่าใช้จ่าย / ผลประโยชน์เพื่อสนับสนุนความถูกต้องในระดับนั้น ในแอป LOB สำหรับผู้ชมที่ถูกจับในบางครั้งประโยชน์ทางธุรกิจมากที่สุดสำหรับค่าใช้จ่ายเกี่ยวกับรายงานข้อผิดพลาดคือการเพิ่มบรรทัดลงในเอกสารที่ระบุว่า "อย่าทำเช่นนั้น"
Bill

3

เครื่องมือวิธีที่เป็นทางการบางอย่าง (เช่นFrama-Cสำหรับซอฟต์แวร์ฝังตัว C ที่สำคัญ) สามารถดูได้ว่าเป็น (การเรียงลำดับ) การจัดเตรียมหรืออย่างน้อยการตรวจสอบการพิสูจน์ความถูกต้องของซอฟต์แวร์ที่กำหนด (Frama-C ตรวจสอบว่าโปรแกรมปฏิบัติตามข้อกำหนดอย่างเป็นทางการในบางแง่และเคารพค่าคงที่ที่มีคำอธิบายประกอบอย่างชัดเจนในโปรแกรม)

ในบางส่วนอาจใช้วิธีการอย่างเป็นทางการเช่นDO-178Cสำหรับซอฟต์แวร์สำคัญในเครื่องบินพลเรือน ดังนั้นในบางกรณีแนวทางดังกล่าวเป็นไปได้และเป็นประโยชน์

แน่นอนว่าการพัฒนาซอฟต์แวร์รถบั๊กน้อยนั้นมีค่าใช้จ่ายสูงมาก แต่วิธีการแบบเป็นทางการเหมาะสมสำหรับซอฟต์แวร์บางประเภท หากคุณพูดในแง่ร้ายคุณอาจคิดว่าข้อผิดพลาดจะถูกย้ายจากโค้ดไปเป็นสเปคอย่างเป็นทางการ (ซึ่งอาจมี "บั๊ก" บางส่วนเนื่องจากการทำให้พฤติกรรมที่เป็นทางการของซอฟต์แวร์เป็นเรื่องยากและมีแนวโน้มผิดพลาด)


3

ฉันสะดุดกับคำถามนี้และฉันคิดว่าลิงก์นี้อาจน่าสนใจ:

การใช้งานในอุตสาหกรรมของAstrée

การพิสูจน์ว่าไม่มี RTE ในระบบที่ใช้โดยแอร์บัสที่มีโค้ดมากกว่า 130K ในปี 2003 ดูเหมือนจะไม่เลวและฉันสงสัยว่าจะมีใครบอกว่านี่ไม่ใช่โลกแห่งความเป็นจริง


2

ไม่สุภาษิตทั่วไปสำหรับเรื่องนี้คือ "ในทางทฤษฎีทฤษฎีและการปฏิบัติเหมือนกันในทางปฏิบัติไม่ใช่"

ตัวอย่างง่ายๆหนึ่งอย่าง: Typos

การใช้งานรหัสจริงผ่านการทดสอบหน่วยค้นหาสิ่งต่าง ๆ เกือบจะในทันทีและชุดการทดสอบที่เหนียวแน่นจะลบล้างความจำเป็นในการพิสูจน์อย่างเป็นทางการ กรณีการใช้งานทั้งหมด - ดี, ไม่ดี, ข้อผิดพลาดและกรณีขอบ - ควรระบุในการทดสอบหน่วยซึ่งท้ายสุดเป็นข้อพิสูจน์ที่ดีกว่ารหัสนั้นถูกต้องกว่าการพิสูจน์ใด ๆ ที่แยกจากรหัส

โดยเฉพาะอย่างยิ่งหากความต้องการเปลี่ยนแปลงหรืออัลกอริทึมได้รับการปรับปรุงเพื่อแก้ไขข้อบกพร่อง - การพิสูจน์อย่างเป็นทางการมีแนวโน้มที่จะล้าสมัยเช่นเดียวกับความคิดเห็นของรหัสมักจะได้รับ


3
ไม่ถูกต้อง. ไม่มีการทดสอบหน่วยใดที่จะสามารถครอบคลุมพารามิเตอร์ที่เป็นไปได้ทั้งหมด ลองนึกภาพ "การทดสอบหน่วย" คอมไพเลอร์ด้วยวิธีนี้ทำให้แน่ใจว่าไม่มีการเปลี่ยนความหมายผ่าน
SK-logic

3
การทดสอบหน่วยไม่ใช่จอกศักดิ์สิทธิ์ ...
Ryathal

1
@Winston Ewert มีคอมไพเลอร์ที่ผ่านการตรวจสอบแล้ว (และแอสเซมเบลอร์ที่ยืนยันแล้วจำนวนมาก) และฮาร์ดแวร์มีการตรวจสอบอย่างเป็นทางการบ่อยกว่าซอฟต์แวร์ ดูที่นี่: gallium.inria.fr/~xleroy/publi/compiler-certif.pdf
SK-logic

1
@ SK-logic ใช่มีคอมไพเลอร์ของเล่นที่พิสูจน์แล้วว่าถูกต้องเพื่อวัตถุประสงค์ทางวิชาการ แต่ผู้ใช้คอมไพเลอร์เกี่ยวกับอะไรใช้จริง? ฉันสงสัยว่าคอมไพเลอร์ส่วนใหญ่จะถูกตรวจสอบโดยใช้การทดสอบอัตโนมัติหลายรูปแบบและแทบจะไม่มีการพิสูจน์ที่ถูกต้องเป็นทางการ
Winston Ewert

1
@Winston Ewert พิสูจน์ความถูกต้องเป็นจริงและใช้กันอย่างแพร่หลายในชีวิตจริง สิ่งที่ใช้ไม่ได้จริง ๆ เป็นภาษากระแสหลักส่วนใหญ่ ฉันหวังว่าพวกเขาทั้งหมดจะตายไปดังนั้นมูลค่าของการพิสูจน์ความถูกต้องจะเพิ่มขึ้นในอนาคต
SK-logic

1

ฉันคิดว่าข้อ จำกัด ที่กำหนดไว้ในการพิสูจน์ความถูกต้องเนื่องจากปัญหาการหยุดชะงักอาจเป็นอุปสรรคที่ใหญ่ที่สุดในการพิสูจน์ความถูกต้องกลายเป็นกระแสหลัก


8
ปัญหาการหยุดทำงานบอกว่าเราไม่สามารถตัดสินได้ว่าโปรแกรมใด ๆ หยุดทำงานหรือไม่ โปรแกรมเหล่านี้สามารถทำสิ่งที่แปลกประหลาดได้เช่นทดสอบจำนวนเต็มทุกตัวเพื่อดูว่าเป็น Mersenne prime หรือไม่ เราไม่ได้ทำในโปรแกรมปกติ!
Casebash

1
@Casebash คำถามคือมีชุดย่อยที่มีประโยชน์ของโปรแกรมที่สามารถแก้ไขปัญหาการหยุดได้หรือไม่ ไม่ว่าจะด้วยวิธีใดก็ตาม เช่นเราสามารถ จำกัด โปรแกรมของเราเพื่อให้เราไม่สามารถทำสิ่งต่าง ๆ เช่นทดสอบจำนวนเต็มโดยไม่ทำลายความสามารถในการทำงานที่มีประโยชน์หรือไม่
Winston Ewert

1

มันถูกใช้โดยทุกคนแล้ว ทุกครั้งที่คุณใช้การตรวจสอบประเภทภาษาการเขียนโปรแกรมของคุณคุณจะต้องทำการพิสูจน์ทางคณิตศาสตร์ของความถูกต้องของโปรแกรมของคุณ วิธีนี้ใช้ได้ผลดีมาก - คุณเพียงแค่ต้องเลือกประเภทที่ถูกต้องสำหรับทุกฟังก์ชั่นและโครงสร้างข้อมูลที่คุณใช้ ยิ่งมีความแม่นยำมากเท่าไหร่การตรวจสอบของคุณก็จะยิ่งดีขึ้นเท่านั้น ประเภทที่มีอยู่ในภาษาการเขียนโปรแกรมมีเครื่องมือที่ทรงพลังพอที่จะอธิบายพฤติกรรมที่เป็นไปได้เกือบทั้งหมด ใช้ได้กับทุกภาษา C ++ และภาษาสแตติกกำลังทำการตรวจสอบในเวลาคอมไพล์ขณะที่ภาษาไดนามิกมากขึ้นเช่นไพ ธ อนกำลังทำเมื่อโปรแกรมรัน การตรวจสอบยังคงมีอยู่ในทุกภาษาเหล่านี้ (ตัวอย่างเช่น c ++ รองรับการตรวจสอบผลข้างเคียงเช่นเดียวกับที่ haskell ทำ


ด้วยบิตเกี่ยวกับผลข้างเคียงใน C ++ คุณหมายถึงความถูกต้อง const หรือไม่
Winston Ewert

ใช่ฟังก์ชั่นสมาชิก const + const หากฟังก์ชันสมาชิกทั้งหมดของคุณเป็น const ข้อมูลทั้งหมดในวัตถุจะไม่สามารถแก้ไขได้
tp1

พวกเขายังคงสามารถแก้ไขได้ถ้าคุณใช้หรือmutable const_castแน่นอนฉันเห็นการเชื่อมต่อที่คุณวาดที่นั่น แต่รสชาติของสองวิธีดูเหมือนจะค่อนข้างแตกต่างจากฉัน
Winston Ewert

นั่นเป็นเหตุผลที่คุณต้องเลือกใช้มัน - มีวิธีในการใช้งานอยู่เสมอ แต่สิ่งที่สำคัญคือการทำให้คอมไพเลอร์ตรวจสอบปัญหาในพื้นที่
tp1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.