পার্শ্ব প্রতিক্রিয়া, অনিয়ন্ত্রিত উত্তরাধিকার এবং null
প্রতিটি ধরণের সদস্য হওয়ার কারণে ওওপি বিশ্বে একটি প্রমাণ আরও শক্ত । সর্বাধিক প্রমাণগুলি আপনি প্রতিটি সম্ভাবনা coveredেকে রেখেছেন তা দেখানোর জন্য অন্তর্ভুক্তির নীতির উপর নির্ভর করে এবং এই সমস্ত 3 টি বিষয়ই প্রমাণ করা শক্ত করে তোলে।
আসুন আমরা বলি যে আমরা বাইনারি গাছগুলি প্রয়োগ করছি যা পূর্ণসংখ্যার মানগুলি ধারণ করে (সিনট্যাক্সকে সহজ রাখার জন্য, আমি এতে জেনেরিক প্রোগ্রামিং আনব না, যদিও এতে কোনও পরিবর্তন হয় না)) স্ট্যান্ডার্ড এমএলে, আমি এটির মতো সংজ্ঞা দেব এই:
datatype tree = Empty | Node of (tree * int * tree)
এটি এমন একটি নতুন প্রকারের পরিচয় দেয় tree
যার মান দুটি ধরণের (বা ক্লাসগুলি, কোনও শ্রেণীর ওওপি ধারণার সাথে বিভ্রান্ত না হওয়ার জন্য) আসতে পারে - এমন একটি Empty
মান যা কোনও তথ্য বহন করে না, এবং এমন Node
মানগুলি যেখানে 3 টি দ্বিগুণ থাকে যা প্রথম এবং শেষ হয় last উপাদানগুলি tree
হ'ল এবং যার মাঝারি উপাদানটি একটি int
। ওওপি-তে এই ঘোষণার নিকটতম সান্নিধ্যটি এর মতো দেখতে পাবেন:
public class Tree {
private Tree() {} // Prevent external subclassing
public static final class Empty extends Tree {}
public static final class Node extends Tree {
public final Tree leftChild;
public final int value;
public final Tree rightChild;
public Node(Tree leftChild, int value, Tree rightChild) {
this.leftChild = leftChild;
this.value = value;
this.rightChild = rightChild;
}
}
}
সাবধানতার সাথে গাছের ধরণের পরিবর্তনশীল কখনই হতে পারে না null
।
এখন গাছের উচ্চতা (বা গভীরতা) গণনা করার জন্য একটি ফাংশন লিখি এবং ধরে নিই যে আমাদের এমন কোনও max
ফাংশনে অ্যাক্সেস রয়েছে যা দুটি সংখ্যার বেশিকে প্রদান করে:
fun height(Empty) =
0
| height(Node (leftChild, value, rightChild)) =
1 + max( height(leftChild), height(rightChild) )
আমরা height
কেস দ্বারা ফাংশনটি সংজ্ঞায়িত করেছি - Empty
গাছের জন্য একটি সংজ্ঞা এবং Node
গাছগুলির জন্য একটি সংজ্ঞা রয়েছে । সংকলক জানে যে কত শ্রেণীর গাছ বিদ্যমান এবং যদি আপনি উভয় ক্ষেত্রেই সংজ্ঞা না দেন তবে একটি সতর্কতা জারি করবে। অভিব্যক্তি Node (leftChild, value, rightChild)
ফাংশন স্বাক্ষরে ভেরিয়েবল 3-tuple মান binds leftChild
, value
এবং rightChild
যথাক্রমে তাই আমরা ফাংশন সংজ্ঞা তাদের কাছে পাঠাতে পারেন। এটি ওওপি ভাষায় স্থানীয় ভেরিয়েবলগুলি ঘোষিত করার অনুরূপ:
Tree leftChild = tuple.getFirst();
int value = tuple.getSecond();
Tree rightChild = tuple.getThird();
আমরা কীভাবে প্রমাণ করতে পারি যে আমরা height
সঠিকভাবে প্রয়োগ করেছি ? আমরা স্ট্রাকচারাল ইন্ডাকশন ব্যবহার করতে পারি , যা এর সমন্বয়ে গঠিত: ১. height
আমাদের tree
প্রকারের ( Empty
) এর বেস কেসগুলিতে এটি সঠিক কিনা তা প্রমাণ করুন ২. পুনরাবৃত্ত কলগুলি height
সঠিক বলে ধরে নিলেন , height
নন-বেস কেসের ক্ষেত্রে এটি সঠিক কিনা তা প্রমাণ করুন ) (যখন গাছটি আসলে ক। Node
)
পদক্ষেপ 1 এর জন্য, আমরা দেখতে পাচ্ছি যে যুক্তিটি যখন Empty
গাছ হয় তখন ফাংশনটি সর্বদা 0 প্রদান করে । এটি একটি গাছের উচ্চতার সংজ্ঞা দিয়ে সঠিক।
পদক্ষেপ 2 এর জন্য, ফাংশনটি ফিরে আসে 1 + max( height(leftChild), height(rightChild) )
। ধরে নিলাম যে পুনরাবৃত্তি কলগুলি সত্যই বাচ্চাদের উচ্চতা ফিরিয়ে দেয়, আমরা দেখতে পাচ্ছি যে এটিও সঠিক।
এবং এটি প্রমাণ পূর্ণ। পদক্ষেপ 1 এবং 2 সম্মিলিত সমস্ত সম্ভাবনা। তবে নোট করুন, আমাদের কোনও রূপান্তর নেই, কোনও নাল নেই এবং ঠিক দুটি জাতের গাছ রয়েছে। এই তিনটি শর্তটি সরিয়ে ফেলুন এবং প্রমাণটি আরও জটিল হয়ে উঠবে, যদি অবাস্তব নয়।
সম্পাদনা: যেহেতু এই উত্তরটি শীর্ষে উঠে গেছে, তাই আমি প্রমাণের কম তুচ্ছ উদাহরণ যুক্ত করতে চাই এবং কাঠামোগত আবেগকে আরও কিছুটা কভার করতে চাই। উপরে আমরা প্রমাণ করেছি যে যদি height
ফেরত দেয় তবে এর ফেরতের মানটি সঠিক। যদিও আমরা প্রমাণ করি নি যে এটি সর্বদা একটি মান দেয়। এটি প্রমাণ করার জন্য আমরা স্ট্রাকচারাল ইন্ডাকশনও ব্যবহার করতে পারি (বা অন্য কোনও সম্পত্তি)) আবার, ২ য় ধাপের সময়, আমাদের পুনরাবৃত্ত কলগুলি যতক্ষণ না পুনরাবৃত্ত কলগুলি সমস্ত প্রত্যক্ষ প্রত্যক্ষ সন্তানের উপর পরিচালিত হয় ততক্ষণ সম্পত্তিটি ধরে নেওয়ার অনুমতি দেওয়া হয় গাছ।
একটি ক্রিয়াকলাপ দুটি পরিস্থিতিতে কোনও মান ফিরিয়ে দিতে ব্যর্থ হতে পারে: যদি এটি ব্যতিক্রম ছুঁড়ে ফেলে এবং যদি এটি চিরকালের জন্য লুপ করে। প্রথমে প্রমাণ করুন যে কোনও ব্যতিক্রম ছুঁড়ে দেওয়া না হলে, ফাংশনটি সমাপ্ত হয়:
প্রমাণ করুন (যদি কোনও ব্যতিক্রম না ছুঁড়ে দেওয়া হয়) তবে বেস কেসগুলির জন্য ফাংশনটি সমাপ্ত হয় ( Empty
)। যেহেতু আমরা নিঃশর্ত 0 ফেরত, এটি সমাপ্ত হয়।
প্রমাণ করুন যে ফাংশনটি বেস-বেসগুলিতে ( Node
) বন্ধ হয়ে যায়। তিনটি ফাংশন কল এখানে দেওয়া হল: +
, max
, এবং height
। আমরা তা জানি +
এবং max
শেষ করব কারণ তারা ভাষার মানক গ্রন্থাগারের অংশ এবং তারা সেভাবে সংজ্ঞায়িত হয়েছে। পূর্বে উল্লিখিত হিসাবে, আমরা যে সম্পত্তিটি আমরা প্রমাণ করার চেষ্টা করছি তা ধরে নেওয়ার অনুমতি দেওয়া হচ্ছে যতক্ষণ না তারা তাত্ক্ষণিক সাবট্রিতে কাজ করে, সুতরাং কলটিও height
বন্ধ করার জন্য।
যে প্রমাণ শেষ। মনে রাখবেন যে আপনি ইউনিট পরীক্ষা দিয়ে সমাপ্তি প্রমাণ করতে পারবেন না। এখন যা বাকী রয়েছে তা প্রদর্শন height
ব্যতিক্রমগুলি ছুঁড়ে না ফেলে।
- প্রমাণ
height
করুন যা বেস কেস ( Empty
) এ ব্যতিক্রম করে না । 0 রিটার্নিং একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে না, তাই আমরা সম্পন্ন করেছি।
height
নন-বেস কেস ( Node
) -র ক্ষেত্রে এটি ব্যতিক্রম হয় না তা প্রমাণ করুন । আবারও ধরে নিন যে আমরা জানি +
এবং max
ব্যতিক্রমগুলি ছুঁড়ে না ফেলে। এবং কাঠামোগত আনয়ন আমাদের পুনরাবৃত্ত কলগুলি নিক্ষেপ করবে না ধরে নিতে দেয় (কারণ গাছের তাত্ক্ষণিক শিশুদের উপর কাজ করে)) তবে অপেক্ষা করুন! এই ফাংশনটি পুনরাবৃত্ত হয়, তবে লেজ পুনরাবৃত্ত হয় না । আমরা স্ট্যাক উড়িয়ে দিতে পারে! আমাদের চেষ্টা করা প্রমাণটি একটি বাগ উন্মোচিত করেছে। লেজ পুনরাবৃত্ত হিসাবে পরিবর্তনheight
করে আমরা এটি ঠিক করতে পারি ।
আমি আশা করি এই শো প্রমাণগুলি ভীতিজনক বা জটিল হতে হবে না। প্রকৃতপক্ষে, আপনি যখনই কোড লিখবেন, আপনি অনানুষ্ঠানিকভাবে আপনার মাথায় একটি প্রমাণ তৈরি করেছেন (অন্যথায়, আপনি কেবলমাত্র ফাংশনটি বাস্তবায়িত করেছেন তা আপনি বিশ্বাস করতে পারবেন না)) নাল, অপ্রয়োজনীয় পরিবর্তন এবং অনিচ্ছাকৃত উত্তরাধিকার এড়িয়ে আপনি আপনার স্বজ্ঞাততা প্রমাণ করতে পারবেন মোটামুটি সহজেই সংশোধন করুন। এই বিধিনিষেধগুলি ততটা কঠোর নয় যতটা আপনি ভাবেন:
null
এটি একটি ভাষার ত্রুটিযুক্ত এবং এটি থেকে দূরে থাকা নিঃশর্তভাবে ভাল।
- মিউটেশনটি কখনও কখনও অনিবার্য এবং প্রয়োজনীয় হয় তবে এটি আপনি যা ভাবেন তার চেয়ে অনেক কম প্রয়োজন হয় especially বিশেষত যখন আপনার অবিরাম ডেটা কাঠামো থাকে।
- যেমন সীমাবদ্ধ সংখ্যক ক্লাস (ক্রিয়ামূলক অর্থে) / উপশ্রেণী (ওওপি অর্থে) এর সীমাহীন সংখ্যা বনাম, এটি একটি একক উত্তরের জন্য খুব বড় বিষয় । সেখানে ডিজাইনের বাণিজ্য বন্ধ রয়েছে বলে যথেষ্ট - এক্সটেনশনের স্বচ্ছতা বনাম স্বচ্ছতার সম্ভাবনা।