เป็นไปได้ไหมที่จะแก้ปัญหาการหยุดชะงักหากคุณมีข้อ จำกัด หรืออินพุตที่คาดการณ์ได้?


18

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

ตัวอย่างเช่นดูเหมือนว่าภาษาที่ไม่อนุญาตการวนซ้ำนั้นจะง่ายมากที่จะบอกได้ว่าโปรแกรมจะหยุดหรือไม่

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

คำตอบ:


10

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

recursion

ข้อ จำกัด ที่พบบ่อยในภาษาสคริปต์คือการป้องกันการเรียกซ้ำแบบไดนามิก: ถ้าการโทร B โทร C การโทร…โทร A จากนั้นล่าม (หรือตัวตรวจสอบในกรณีของคุณ) ให้ขึ้นหรือส่งสัญญาณข้อผิดพลาดแม้ว่าการเรียกซ้ำอาจยุติลงจริง ตัวอย่างที่เป็นรูปธรรมสองตัวอย่าง:

  • ตัวประมวลผลล่วงหน้า C ปล่อยแมโครให้ไม่เสียหายขณะที่กำลังขยายแมโครนั้น การใช้งานทั่วไปคือการกำหนด wrapper รอบฟังก์ชัน:

    #define f(x) (printf("calling f(%d)\n", (x)), f(x))
    f(3);
    

    สิ่งนี้ขยายไป

    (printf("calling f(%d)\n", (3)), f(3))
    

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

    #define f0(x) x(x)x(x)
    #define f1(x) f0(f0(x))
    #define f2(x) f1(f1(x))
    #define f3(x) f2(f2(x))
    f3(x)
    
  • หอย Unix ขยายนามแฝงซ้ำ แต่เฉพาะเมื่อพวกเขาพบนามแฝงที่ถูกขยายไปแล้ว อีกครั้งวัตถุประสงค์หลักคือการกำหนดนามแฝงสำหรับคำสั่งที่มีชื่อคล้ายกัน

    alias ls='ls --color'
    alias ll='ls -l'
    

nn

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

ลูป

forม.n

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


4

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


4

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

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

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

เกี่ยวกับคำถามอื่น ๆ ถ้าคุณ จำกัด อินพุตให้เพียงพอปัญหาการหยุดชะงักอาจเป็นเรื่องง่าย ตัวอย่างเช่นหากคุณรู้ว่าอินพุตเป็นอัลกอริธึมเวลาพหุนามการตัดสินใจว่าปัญหาการหยุดพักสำหรับพวกเขานั้นเล็กน้อยมาก

ปัญหาที่เกิดขึ้นในวิธีการแบบทางการมักไม่สามารถตัดสินใจได้คุณอาจต้องการตรวจสอบวรรณกรรมเกี่ยวกับวิธีที่พวกเขาจัดการกับปัญหาเหล่านี้ในทางปฏิบัติ


4

ไม่ใช่คำตอบที่เข้มงวดอย่างเป็นทางการ แต่ตรงนี้มันไป:

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

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

gotos โดยพลการมักจะไม่ดี ย้อนกลับ - gotos มีแนวโน้มที่จะนำไปสู่ลูปที่อาจไม่มีที่สิ้นสุด

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


2

คุณต้องให้คำจำกัดความของภาษาสคริปต์ของคุณและคุณหมายถึงอะไรโดย "คาดหวัง" จากผู้เขียนสคริปต์

O(nω)

มีผลลัพธ์ที่คล้ายกันสำหรับโปรแกรมพหุนามชั้นหนึ่งโดย Aaron R. Bradley, Zohar Manna และ Henny B. Sipma แต่ AFAIK (ฉันอาจจะผิดที่นี่) รันไทม์เป็นทวีคูณทวีคูณ (เป็นหลักเวลาที่จำเป็นในการคำนวณพื้นฐาน Groebner)

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