হ্যাঁ, বাছাই করা রুটিনের জন্য একটি সুনির্দিষ্ট প্রকারের প্রকাশ করা সম্ভব যেমন এই ধরণের কোনও ফাংশন অবশ্যই ইনপুট তালিকাটিকে বাছাই করতে পারে।
আরও উন্নত এবং মার্জিত সমাধান থাকতে পারে, আমি একটি প্রাথমিক স্কেচ করব, কেবলমাত্র।
আমরা কক-জাতীয় স্বরলিপি ব্যবহার করব। আমরা একটি প্রিকিকেট সংজ্ঞা দিয়ে শুরু করি যা প্রয়োজনীয়তার জন্য অনুমতি f: nat -> nat
হিসাবে কাজ করে0..n−1:
Definition permutation (n: nat) (f: nat -> nat): Prop :=
(* once restricted, its codomain is 0..n-1 *)
(forall m, m < n -> f m < n) /\
(* it is injective, hence surjective *)
(forall m1 m2, m1 < n -> m2 < n -> f m1 = f m2 -> m1 = m2) .
একটি সহজ লেমা সহজেই প্রমাণ করা যায়।
Lemma lem1: forall n f, permutation n f -> m < n -> f m < n.
... (* from the def *)
আমরা কি সংজ্ঞায়িত mদৈর্ঘ্যযুক্ত একটি তালিকার তম উপাদান n। এই ফাংশনটির একটি প্রমাণের প্রয়োজন h
যা উল্লেখ করেm<n সত্যিই ধরে।
Definition nth {A} {n} (l: list A n) m (h : m < n): A :=
... (* recursion over n *)
অর্ডার দেওয়ার পরে A
, আমরা প্রকাশ করতে পারি যে একটি তালিকা সাজানো হয়েছে:
Definition ordering (A: Type) :=
{ leq: A->A->bool |
(* axioms for ordering *)
(forall a, leq a a = true) /\
(forall a b c, leq a b = true -> leq b c = true -> leq a c = true) /\
(forall a b, leq a b = true -> leq b a = true -> a = b)
} .
Definition sorted {A} {n} (o: ordering A) (l: list A n): Prop :=
...
অবশেষে এখানে বাছাই অ্যালগরিদমের ধরণ রয়েছে:
Definition mysort (A: Type) (o: ordering A) (n: nat) (l: list A n):
{s: list A n | sorted o s /\
exists f (p: permutation n f),
forall (m: nat) (h: m < n),
nth l m h = nth s (f m) (lem1 n f p h) } :=
... (* the sorting algorithm, and a certificate for its output *)
আউটপুট টাইপ যে ফলাফলের তালিকা s
হয়n উপাদান দীর্ঘ, এটি বাছাই করা হয়, এবং এটির একটি অনুমানের ক্রম রয়েছে 0..n−1যা l
আউটপুট তালিকার মধ্যে ইনপুট তালিকার উপাদানগুলিকে মানচিত্র করে s
। নোট করুন যে প্রমাণ করতে আমাদের উপরের লেমাকে অনুরোধ করতে হবেf(m)<n, যা দ্বারা প্রয়োজনীয় nth
।
তবে নোট করুন যে এটি ব্যবহারকারী, অর্থাৎ প্রোগ্রামার, যা তাদের বাছাই করা অ্যালগরিদমকে সঠিক প্রমাণ করতে হবে। সংকলকটি কেবল যাচাই করা ঠিক আছে তা যাচাই করবে না: এটি যা করে তা সরবরাহিত প্রমাণ পরীক্ষা করে। প্রকৃতপক্ষে, সংকলক এর চেয়ে বেশি কিছু করতে পারে না: যেমন "এই প্রোগ্রামটি একটি বাছাই করা অ্যালগরিদম" এর মতো অর্থবোধক বৈশিষ্ট্যগুলি অনস্বীকার্য (রাইস উপপাদ্য দ্বারা), সুতরাং আমরা প্রমাণী পদক্ষেপটি সম্পূর্ণ স্বয়ংক্রিয়ভাবে তৈরি করার আশা করতে পারি না।
সুদূর, সুদূর ভবিষ্যতে আমরা এখনও আশা করতে পারি যে স্বয়ংক্রিয় উপপাদ্য প্রবাদীরা এত স্মার্ট হয়ে উঠেছে যে "বেশিরভাগ" ব্যবহারিকভাবে ব্যবহৃত অ্যালগরিদমগুলি স্বয়ংক্রিয়ভাবে সঠিক প্রমাণিত হতে পারে। ধানের উপপাদ্যটি কেবলমাত্র বলে যে এটি সব ক্ষেত্রেই করা যায় না। আমরা যা আশা করতে পারি সেগুলি হ'ল একটি সঠিক, ব্যাপকভাবে প্রয়োগযোগ্য, তবে অন্তর্নিহিত অসম্পূর্ণ সিস্টেম।
চূড়ান্ত নোট হিসাবে, কখনও কখনও এটি ভুলে যায় যে সাধারণ টাইপ সিস্টেমগুলিও অসম্পূর্ণ ! যেমন জাভাতেও
int f(int x) {
if (x+2 != 2+x)
return "Houston, we have a problem!";
return 42;
}
শব্দার্থগতভাবে নিরাপদ টাইপ করুন (এটি সর্বদা একটি পূর্ণসংখ্যা ফেরত দেয়), তবে প্রকারের পরীক্ষকটি অ্যাক্সেসযোগ্য রিটার্ন সম্পর্কে অভিযোগ করবেন।