العودية البسيطة

العودية مفهوم قوي في Scheme: تستدعي الدالة نفسها لحل مشكلات فرعية أصغر من المشكلة الأصلية. يتضمن نمط العودية البسيطة حالة أساسية لإيقاف التكرار وحالة عودية لتقليل المشكلة.

يبدو الهيكل العام للدالة العودية كالتالي:

(define (function-name args)
  (if (base-condition)
    base-result
    (recursive-call)))
  • الحالة الأساسية: إيقاف التكرار.
  • النتيجة الأساسية: القيمة المُرجَعة عند تحقق الشرط الأساسي.
  • الاستدعاء العودي: استدعاء الدالة نفسها بوسائط معدّلة تقرّب الحساب من الحالة الأساسية.

مثال: مجموع الأرقام (من 1 إلى n)

دالة عودية بسيطة لحساب مجموع الأرقام من 1 إلى n:

(define (sum-to-n n)
  (if (= n 0)                  ; الحالة الأساسية: التوقف عندما n = 0
    0                          ; النتيجة الأساسية: المجموع 0
    (+ n (sum-to-n (- n 1))))) ; استدعاء عودي: جمع n الحالي مع نتيجة المشكلة الأصغر

كيف يعمل: التفكيك وإعادة التجميع

تعمل العودية بتقسيم المشكلة الأصلية إلى أجزاء أصغر. يعالج كل استدعاء قطعة واحدة ويمرّر الباقي. عند الوصول إلى أبسط حالة، تُعاد تجميع النتائج مع اكتمال الحساب.

تتبّع خطوة بخطوة لـ (sum-to-n 3)

  1. الاستدعاء الأول: (sum-to-n 3)(+ 3 (sum-to-n 2))

  2. الاستدعاء الثاني: (sum-to-n 2)(+ 2 (sum-to-n 1))

  3. الاستدعاء الثالث: (sum-to-n 1)(+ 1 (sum-to-n 0))

  4. الحالة الأساسية: (sum-to-n 0)0


إعادة تجميع النتيجة النهائية

بمجرد حل أبسط حالة، تكتمل كل طبقة من العمليات الحسابية:

  1. (sum-to-n 0) يعطي 0
  2. (sum-to-n 1) يصبح (+ 1 0) = 1
  3. (sum-to-n 2) يصبح (+ 2 1) = 3
  4. (sum-to-n 3) يصبح (+ 3 3) = 6

مثال: طباعة كل عنصر في قائمة

دالة عودية بسيطة لطباعة كل عنصر في قائمة:

(define (print-elements lst)
  (if (null? lst)
    (lumi-message "done")
    (begin
      (lumi-message (number->string (car lst))) ; طباعة العنصر الأول
      (print-elements (cdr lst)))))             ; معالجة بقية القائمة
  • الحالة الأساسية: إذا كانت القائمة فارغة (null? lst)، أوقف التكرار.
  • الحالة العودية: اطبع العنصر الأول (car lst)، ثم استدعِ الدالة على بقية القائمة (cdr lst).

مثال للاستخدام

(print-elements (list 1 2 3))

الإخراج:

  • "1"
  • "2"
  • "3"

النتيجة: "done"


كيف يعمل

  1. تسترد الدالة العنصر الأول بـ car وتعالجه.
  2. ثم تستدعي نفسها على بقية القائمة (cdr).
  3. تتكرر العملية حتى تصبح القائمة فارغة (null? lst).

ملخص

  • العودية البسيطة تتكون من:
    1. حالة أساسية: إيقاف التكرار.
    2. حالة عودية: تقلّل المشكلة نحو الحالة الأساسية.
  • كل استدعاء عودي يقرّب الحساب من الاكتمال.
  • عند الوصول إلى الحالة الأساسية، تُدمَج النتائج مع اكتمال التكرار.

تعكس العودية بنية المشكلة وتوفر تدفقًا منطقيًا واضحًا. تأكّد دائمًا من وجود حالة أساسية لتجنّب التكرار اللانهائي.