โปรแกรมความถูกต้องสเปค


17

จากวิกิพีเดีย: ในทางวิทยาการคอมพิวเตอร์เชิงทฤษฎีความถูกต้องของอัลกอริทึมถูกยืนยันเมื่อมีการกล่าวว่าอัลกอริทึมนั้นถูกต้องตามข้อกำหนด

แต่ปัญหาคือการได้สเปค "ที่เหมาะสม" ไม่ใช่งานที่ไม่สำคัญและไม่มีวิธีการที่ถูกต้อง 100% (เท่าที่ฉันรู้) เพื่อให้ได้สิ่งที่ถูกต้องมันเป็นเพียงการประมาณดังนั้นถ้าเราจะ ใช้เพรดิเคตเป็นสเปคเพียงเพราะมัน "ดูเหมือน" เหมือน "หนึ่ง" ทำไมไม่ลองใช้โปรแกรมให้ถูกต้องเพียงเพราะมัน "ดู" ถูกต้อง?


2
เพราะหวังว่าข้อมูลจำเพาะจะซับซ้อนน้อยกว่าโปรแกรมดังนั้นมันจะมีข้อผิดพลาดน้อยกว่าโปรแกรม
user253751

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

@immibis แต่ถ้ามีข้อผิดพลาดเพียงครั้งเดียวสิ่งทั้งหมดผิด
Maykel Jakson

@MaykelJakson จริง ... ฉันเคยขัดแย้งในความจริงใน Rodin โดยไม่ได้ตั้งใจ (สิ่งที่ฉันพยายามจะทำนั้นถูกต้อง แต่ไวยากรณ์ผิด) ฉันใช้เวลาสักครู่ในการ "อืมช่างคิดอัตโนมัติดูเหมือนจะทำงานผิดปกติได้ดีในตอนนี้" ก่อนที่ฉันจะสังเกตเห็น
253751

คำตอบ:


30

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

มีหลายสาเหตุที่กระบวนการนี้ยังคงมีประโยชน์อยู่

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

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

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

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

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

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

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


ในขณะที่สเป็คมีรายละเอียดมากขึ้นความน่าจะเป็นที่จะถูกเขียนเป็น pseudocode เพิ่มขึ้น ใช้ตัวอย่างการเรียงลำดับของคุณรุ่นที่มีรายละเอียดมากขึ้นของ "เอาต์พุตจะต้องอยู่ในลำดับที่เพิ่มขึ้น" จะเป็น "จำนวนเต็มทุกตัวในผลลัพธ์หลังจากแรกต้องมีขนาดใหญ่กว่าหมายเลขก่อนหน้า" นี้ในการเปิดสามารถเขียนได้อย่างง่ายดายเป็นสิ่งที่ต้องการfor each integer I<sub> N</ sub> in set S (where N > 1) { assert I<sub> N</ sub> > I<sub> N - 1</ }sub> ไม่แน่ใจ 100% เกี่ยวกับสัญกรณ์
Justin Time - Reinstate Monica

ดังนั้นข้อมูลจำเพาะที่ดียังสามารถช่วยสร้างโค้ดได้
Justin Time - Reinstate Monica

1
วิธีที่ชัดเจนในการประมวลผลข้อมูลการเรียงลำดับคือการแจกแจงเรียงสับเปลี่ยนทั้งหมดของอินพุตและเลือกลำดับที่สั่ง แม้ว่าปัญหานี้ควรชัดเจน ...
Derek Elkins ออกจาก SE

19

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

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

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

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

เป็นไปไม่ได้ที่จะตรวจสอบให้แน่ใจว่าข้อกำหนดถูกต้อง ตัวอย่างเช่นหากคุณทำผิดฟิสิกส์เบรกอาจไม่มีประสิทธิภาพแม้ว่าคณิตศาสตร์ที่เกี่ยวข้องกับรหัสเบรกกับความต้องการอย่างเป็นทางการนั้นถูกต้อง ไม่ดีที่จะพิสูจน์ว่าตัวแบ่งมีผลกับโหลด 500 กิโลกรัมถ้าคุณมีน้ำหนักจริง 5000 กิโลกรัม แต่มันง่ายกว่าที่จะเห็นว่า 500 กก. นั้นผิดไปกว่าที่จะเห็นภายในรหัสเบรกว่ามันจะไม่ดีพอสำหรับพารามิเตอร์ทางกายภาพของรถ

¹ ตรงกันข้ามกับแนวทางที่เป็นทางการคือ“ ฉันเดางานนี้ แต่ฉันไม่แน่ใจ” เมื่อคุณวางเดิมพันชีวิตของคุณมันก็ดูไม่ดีนัก


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

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