ফাংশনাল প্রোগ্রামিংয়ে কীভাবে কেউ গাণিতিক আইনের মাধ্যমে মডুলারিটি অর্জন করতে পারেন?


11

আমি এই প্রশ্নে পড়েছি যে কার্যকরী প্রোগ্রামাররা তাদের প্রোগ্রামটি সঠিকভাবে কাজ করছে কিনা তা নিশ্চিত করার জন্য গাণিতিক প্রমাণ ব্যবহার করে tend এটি ইউনিট পরীক্ষার চেয়ে অনেক সহজ এবং দ্রুত শোনায় তবে এটি কোনও ওওপি / ইউনিট পরীক্ষার পটভূমি থেকে আসে আমি কখনই এটি সম্পন্ন করে দেখিনি।

আপনি কি আমাকে এটি ব্যাখ্যা করতে এবং একটি উদাহরণ দিতে পারেন?


7
"এটি ইউনিট পরীক্ষার চেয়ে অনেক সহজ এবং দ্রুত শোনায়"। হ্যাঁ, শোনাচ্ছে। বাস্তবে, বেশিরভাগ সফ্টওয়্যারের পক্ষে এটি কার্যত অসম্ভব। এবং কেন শিরোনাম উল্লেখের মডুলারিটি এখনও আপনার যাচাইয়ের কথা বলছে?
ইউফোরিক

@ ওপিতে ইউফোরিক ইউনিট পরীক্ষায় আপনি যাচাইকরণের জন্য পরীক্ষাগুলি লেখেন ... সফ্টওয়্যারটির একটি অংশ সঠিকভাবে কাজ করছে যাচাইকরণ, তবে আপনার উদ্বেগগুলি পৃথক করা হয়েছে কিনা তা যাচাইকরণ করুন ... অর্থাত্ মড্যুলারিটি এবং পুনঃব্যবস্থা ... যদি আমি এটি সঠিকভাবে বুঝতে পারি।
leeand00

2
@ ইওফোরিক কেবল তখনই যদি আপনি পরিবর্তন এবং উত্তরাধিকারের অপব্যবহার করেন এবং ত্রুটিযুক্ত সিস্টেমের (যেমন আছে null) ভাষায় ভাষায় কাজ করেন ।
ডোভাল

@ লীয়ানড00 আমি মনে করি আপনি "যাচাইকরণ" শব্দটির অপব্যবহার করছেন। সফ্টওয়্যার যাচাইকরণের মাধ্যমে মডুলারালিটি এবং পুনঃব্যবহারযোগ্যতা সরাসরি পরীক্ষা করা হয় না (যদিও অবশ্যই, মড্যুলারটির অভাব সফ্টওয়্যারটিকে বজায় রাখা এবং পুনরায় ব্যবহার করা আরও শক্ত করে তুলতে পারে, সুতরাং বাগ প্রবর্তন এবং যাচাইকরণের প্রক্রিয়া ব্যর্থ করে)।
আন্দ্রেস এফ।

সফ্টওয়্যারটির কিছু অংশ যদি মডিউল পদ্ধতিতে লেখা থাকে তবে তা যাচাই করা অনেক সহজ। সুতরাং আপনার কাছে আসল প্রমাণ থাকতে পারে যে ফাংশনটি কিছু ফাংশনের জন্য সঠিকভাবে কাজ করে, অন্যদের জন্য আপনি ইউনিট পরীক্ষা লিখতে পারেন।
গ্রিজওয়াকো

উত্তর:


22

পার্শ্ব প্রতিক্রিয়া, অনিয়ন্ত্রিত উত্তরাধিকার এবং 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ফেরত দেয় তবে এর ফেরতের মানটি সঠিক। যদিও আমরা প্রমাণ করি নি যে এটি সর্বদা একটি মান দেয়। এটি প্রমাণ করার জন্য আমরা স্ট্রাকচারাল ইন্ডাকশনও ব্যবহার করতে পারি (বা অন্য কোনও সম্পত্তি)) আবার, ২ য় ধাপের সময়, আমাদের পুনরাবৃত্ত কলগুলি যতক্ষণ না পুনরাবৃত্ত কলগুলি সমস্ত প্রত্যক্ষ প্রত্যক্ষ সন্তানের উপর পরিচালিত হয় ততক্ষণ সম্পত্তিটি ধরে নেওয়ার অনুমতি দেওয়া হয় গাছ।

একটি ক্রিয়াকলাপ দুটি পরিস্থিতিতে কোনও মান ফিরিয়ে দিতে ব্যর্থ হতে পারে: যদি এটি ব্যতিক্রম ছুঁড়ে ফেলে এবং যদি এটি চিরকালের জন্য লুপ করে। প্রথমে প্রমাণ করুন যে কোনও ব্যতিক্রম ছুঁড়ে দেওয়া না হলে, ফাংশনটি সমাপ্ত হয়:

  1. প্রমাণ করুন (যদি কোনও ব্যতিক্রম না ছুঁড়ে দেওয়া হয়) তবে বেস কেসগুলির জন্য ফাংশনটি সমাপ্ত হয় ( Empty)। যেহেতু আমরা নিঃশর্ত 0 ফেরত, এটি সমাপ্ত হয়।

  2. প্রমাণ করুন যে ফাংশনটি বেস-বেসগুলিতে ( Node) বন্ধ হয়ে যায়। তিনটি ফাংশন কল এখানে দেওয়া হল: +, max, এবং height। আমরা তা জানি +এবং maxশেষ করব কারণ তারা ভাষার মানক গ্রন্থাগারের অংশ এবং তারা সেভাবে সংজ্ঞায়িত হয়েছে। পূর্বে উল্লিখিত হিসাবে, আমরা যে সম্পত্তিটি আমরা প্রমাণ করার চেষ্টা করছি তা ধরে নেওয়ার অনুমতি দেওয়া হচ্ছে যতক্ষণ না তারা তাত্ক্ষণিক সাবট্রিতে কাজ করে, সুতরাং কলটিও heightবন্ধ করার জন্য।

যে প্রমাণ শেষ। মনে রাখবেন যে আপনি ইউনিট পরীক্ষা দিয়ে সমাপ্তি প্রমাণ করতে পারবেন না। এখন যা বাকী রয়েছে তা প্রদর্শন heightব্যতিক্রমগুলি ছুঁড়ে না ফেলে।

  1. প্রমাণ heightকরুন যা বেস কেস ( Empty) এ ব্যতিক্রম করে না । 0 রিটার্নিং একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে না, তাই আমরা সম্পন্ন করেছি।
  2. heightনন-বেস কেস ( Node) -র ক্ষেত্রে এটি ব্যতিক্রম হয় না তা প্রমাণ করুন । আবারও ধরে নিন যে আমরা জানি +এবং maxব্যতিক্রমগুলি ছুঁড়ে না ফেলে। এবং কাঠামোগত আনয়ন আমাদের পুনরাবৃত্ত কলগুলি নিক্ষেপ করবে না ধরে নিতে দেয় (কারণ গাছের তাত্ক্ষণিক শিশুদের উপর কাজ করে)) তবে অপেক্ষা করুন! এই ফাংশনটি পুনরাবৃত্ত হয়, তবে লেজ পুনরাবৃত্ত হয় না । আমরা স্ট্যাক উড়িয়ে দিতে পারে! আমাদের চেষ্টা করা প্রমাণটি একটি বাগ উন্মোচিত করেছে। লেজ পুনরাবৃত্ত হিসাবে পরিবর্তনheight করে আমরা এটি ঠিক করতে পারি ।

আমি আশা করি এই শো প্রমাণগুলি ভীতিজনক বা জটিল হতে হবে না। প্রকৃতপক্ষে, আপনি যখনই কোড লিখবেন, আপনি অনানুষ্ঠানিকভাবে আপনার মাথায় একটি প্রমাণ তৈরি করেছেন (অন্যথায়, আপনি কেবলমাত্র ফাংশনটি বাস্তবায়িত করেছেন তা আপনি বিশ্বাস করতে পারবেন না)) নাল, অপ্রয়োজনীয় পরিবর্তন এবং অনিচ্ছাকৃত উত্তরাধিকার এড়িয়ে আপনি আপনার স্বজ্ঞাততা প্রমাণ করতে পারবেন মোটামুটি সহজেই সংশোধন করুন। এই বিধিনিষেধগুলি ততটা কঠোর নয় যতটা আপনি ভাবেন:

  • null এটি একটি ভাষার ত্রুটিযুক্ত এবং এটি থেকে দূরে থাকা নিঃশর্তভাবে ভাল।
  • মিউটেশনটি কখনও কখনও অনিবার্য এবং প্রয়োজনীয় হয় তবে এটি আপনি যা ভাবেন তার চেয়ে অনেক কম প্রয়োজন হয় especially বিশেষত যখন আপনার অবিরাম ডেটা কাঠামো থাকে।
  • যেমন সীমাবদ্ধ সংখ্যক ক্লাস (ক্রিয়ামূলক অর্থে) / উপশ্রেণী (ওওপি অর্থে) এর সীমাহীন সংখ্যা বনাম, এটি একটি একক উত্তরের জন্য খুব বড় বিষয় । সেখানে ডিজাইনের বাণিজ্য বন্ধ রয়েছে বলে যথেষ্ট - এক্সটেনশনের স্বচ্ছতা বনাম স্বচ্ছতার সম্ভাবনা।

8
  1. কোডটি যখন অযোগ্য হয় তখন তার পক্ষে যুক্তিযুক্ত হওয়া অনেক সহজ । ফলস্বরূপ, লুপগুলি প্রায়শই পুনরাবৃত্তি হিসাবে লেখা হয়। সাধারণভাবে, পুনরাবৃত্ত সমাধানের যথার্থতা যাচাই করা সহজ easier প্রায়শই, এই জাতীয় সমাধান সমস্যার গাণিতিক সংজ্ঞায় খুব অনুরূপভাবে পড়বে।

    তবে বেশিরভাগ ক্ষেত্রেই সঠিকতার প্রকৃত প্রামাণ্য প্রমাণ সম্পাদনের খুব কম অনুপ্রেরণা রয়েছে। প্রুফগুলি কঠিন, প্রচুর (মানবিক) সময় নিন এবং কম আরওআই করুন।

  2. কিছু কার্যকরী ভাষা (যেমন, এমএল পরিবার থেকে) অত্যন্ত চিত্তাকর্ষক ধরণের সিস্টেম রয়েছে যা সি-স্টাইল টাইপ সিস্টেমের (তবে জেনেরিকের মতো কিছু ধারণা মূলধারার ভাষাগুলিতেও সাধারণ হয়ে উঠেছে) অনেক বেশি গ্যারান্টি দেয়। যখন কোনও প্রোগ্রাম কোনও ধরণের চেক পাস করে, এটি এক ধরণের স্বয়ংক্রিয় প্রমাণ। কিছু ক্ষেত্রে, এটি কিছু ত্রুটি সনাক্ত করতে সক্ষম করবে (উদাহরণস্বরূপ পুনরাবৃত্তিতে বেস কেসটি ভুলে যাওয়া, বা কোনও প্যাটার্ন ম্যাচে নির্দিষ্ট কেসগুলি পরিচালনা করতে ভুলে যাওয়া)।

    অন্যদিকে, এই ধরণের সিস্টেমগুলি সিদ্ধান্ত গ্রহণযোগ্য রাখার জন্য খুব সীমাবদ্ধ রাখতে হবে । তাই এক অর্থে, আমরা নমনীয়তা ছোড় দ্বারা স্ট্যাটিক গ্যারান্টী লাভ - এবং এই নিষেধাজ্ঞা কেন "এর লাইন বরাবর একাডেমিক কাগজপত্র জটিল একটি কারণ হয় একটি মীমাংসিত সমস্যা একটি পরমাণুসদৃশ্য সমাধান, মধ্যে Haskell " বিদ্যমান।

    আমি খুব উদার ভাষা এবং খুব সীমাবদ্ধ ভাষা উভয়ই উপভোগ করি এবং উভয়েরই নিজ নিজ অসুবিধা রয়েছে। তবে কেসটি "ভাল" হতে হবে এমনটি নয়, প্রতিটি আলাদা ধরণের কাজের জন্য আরও সুবিধাজনক।

তারপরে এটি চিহ্নিত করতে হবে যে প্রমাণগুলি এবং ইউনিট পরীক্ষাটি বিনিময়যোগ্য নয়। তারা উভয়ই আমাদের প্রোগ্রামের যথার্থতার সীমাবদ্ধ করতে দেয়:

  • পরীক্ষণটি নির্ভুলতার উপর একটি উচ্চতর আবদ্ধ স্থাপন করে: যদি কোনও পরীক্ষা ব্যর্থ হয়, প্রোগ্রামটি ভুল হয়, যদি কোনও পরীক্ষা ব্যর্থ হয়, তবে আমরা নিশ্চিত যে প্রোগ্রামটি পরীক্ষিত কেসগুলি পরিচালনা করবে, তবে এখনও ত্রুটিযুক্ত ত্রুটি থাকতে পারে।

    int factorial(int n) {
      if (n <= 1) return 1;
      if (n == 2) return 2;
      if (n == 3) return 6;
      return -1;
    }
    
    assert(factorial(0) == 1);
    assert(factorial(1) == 1);
    assert(factorial(3) == 6);
    // oops, we forgot to test that it handles n > 3…
    
  • প্রুফগুলি যথাযথতার উপর কম চাপ দেয়: নির্দিষ্ট বৈশিষ্ট্য প্রমাণ করা অসম্ভব হতে পারে। উদাহরণস্বরূপ, এটি প্রমাণ করা সহজ হতে পারে যে কোনও ফাংশন সর্বদা একটি সংখ্যা ফেরত দেয় (এটিই টাইপ সিস্টেমগুলি করে)। তবে সংখ্যাটি সর্বদা থাকবে তা প্রমাণ করা অসম্ভব < 10

    int factorial(int n) {
      return n;  // FIXME this is just a placeholder to make it compile
    }
    
    // type system says this will be OK…
    

1
"নির্দিষ্ট বৈশিষ্ট্য প্রমাণ করা অসম্ভব ... তবে সংখ্যাটি সর্বদা <10 থাকবে তা প্রমাণ করা অসম্ভব হতে পারে।" যদি প্রোগ্রামটির নির্ভুলতা সংখ্যা 10 এর চেয়ে কম হওয়ার উপর নির্ভর করে তবে আপনি এটি প্রমাণ করতে সক্ষম হবেন। এটি সত্য যে টাইপ সিস্টেমটি (কমপক্ষে এক টন বৈধ প্রোগ্রামগুলি না জানিয়ে না) - তবে আপনি পারেন।
ডোভাল

@ দাওল হ্যাঁ তবে প্রকারের জন্য টাইপ সিস্টেমটি কেবলমাত্র একটি উদাহরণ an প্রকার সিস্টেমগুলি অত্যন্ত দৃশ্যমানভাবে সীমাবদ্ধ এবং নির্দিষ্ট বিবৃতিগুলির সত্যতা মূল্যায়ন করতে পারে না। একজন ব্যক্তি আরও জটিল জটিল প্রমাণগুলি বহন করতে পারে, তবে এখনও সে যা প্রমাণ করতে পারে তার মধ্যে সীমাবদ্ধ থাকবে । এখনও এমন একটি সীমা রয়েছে যা অতিক্রম করা যায় না, এটি কেবল আরও দূরে।
আমন

1
সম্মত, আমি কেবল মনে করি উদাহরণটি কিছুটা বিভ্রান্তিকর ছিল।
ডোভাল

2
নির্ভরশীল টাইপ করা ভাষায়, ইদ্রিসের মতো, এটি এটি 10 ​​এর চেয়েও কম
ইনগো

2
@ ডাবল যে উদ্বেগ নিয়ে আসে তার সমাধানের আরও ভাল উপায় হতে পারে যে কিছু সমস্যা অনস্বীকার্য (উদাহরণস্বরূপ থামানো সমস্যা) প্রমাণ করতে খুব বেশি সময় প্রয়োজন, বা ফলাফলটি প্রমাণের জন্য নতুন গণিত আবিষ্কার করা প্রয়োজন। আমার ব্যক্তিগত মতামতটি হ'ল আপনার স্পষ্ট করে দেওয়া উচিত যে কিছু যদি সত্য প্রমাণিত হয় তবে এটি পরীক্ষা করার একক প্রয়োজন নেই । প্রমাণটি ইতিমধ্যে একটি উপরের এবং নীচে আবদ্ধ রাখে। প্রমাণ এবং পরীক্ষাগুলি বিনিময়যোগ্য না হওয়ার কারণটি হ'ল একটি প্রমাণ করা খুব কঠিন বা সরাসরি করা অসম্ভব। এছাড়াও পরীক্ষাগুলি স্বয়ংক্রিয় করা যেতে পারে (কোড পরিবর্তনের জন্য)।
টমাস এডিং

7

সতর্কতার একটি শব্দটি এখানে ক্রমযুক্ত হতে পারে:

যদিও এখানে অন্যেরা যা লেখেন তা সাধারণত সত্য - সংক্ষেপে, উন্নত প্রকারের সিস্টেমগুলি, অপরিবর্তনীয়তা এবং প্রাসঙ্গিক স্বচ্ছতা সংশোধনের ক্ষেত্রে অনেক বেশি অবদান রাখে - কার্যকরী বিশ্বে টেস্টিং করা হয় না এমনটি নয়। বিপরীতে !

এটি কারণ আমাদের কাছে চিকচেকের মতো সরঞ্জাম রয়েছে যা পরীক্ষার কেসগুলি স্বয়ংক্রিয়ভাবে এবং এলোমেলোভাবে তৈরি করে। আপনি কেবলমাত্র ফাংশনটি অবশ্যই আইনগুলি মেনে চলেনেন এবং তারপরে দ্রুত পরীক্ষাটি শত শত এলোমেলো পরীক্ষার ক্ষেত্রে এই আইনগুলি পরীক্ষা করবে।

আপনি দেখুন, এটি বেশ কয়েকটি পরীক্ষার মামলার ক্ষেত্রে তুচ্ছ সাম্যের চেকের চেয়ে কিছুটা উচ্চতর স্তর।

এখানে একটি এভিএল গাছের প্রয়োগের উদাহরণ রয়েছে:

--- A generator for arbitrary Trees with integer keys and string values
aTree = arbitrary :: Gen (Tree Int String)


--- After insertion, a lookup with the same key yields the inserted value        
p_insert = forAll aTree (\t -> 
             forAll arbitrary (\k ->
               forAll arbitrary (\v ->
                lookup (insert t k v) k == Just v)))

--- After deletion of a key, lookup results in Nothing
p_delete = forAll aTree (\t ->
            not (null t) ==> forAll (elements (keys t)) (\k ->
                lookup (delete t k) k == Nothing))

দ্বিতীয় আইন (বা সম্পত্তি) আমরা নিম্নরূপে পড়তে পারি: সমস্ত স্বেচ্ছাসেবী গাছের জন্য t, নিম্নলিখিতটি ধারণ করে: যদি tখালি না হয় তবে kগাছের সমস্ত কীগুলির জন্য এটি গাছটিকে সরিয়ে রাখার kফলস্বরূপ দেখাবে kথেকে t, ফলাফল হবে Nothing(যা বোঝায়: পাওয়া যায় নি)।

এটি বিদ্যমান কী মুছে ফেলার জন্য যথাযথ কার্যকারিতা পরীক্ষা করে। কোন আইন অ-বিদ্যমান কী মুছে ফেলা পরিচালনা করতে হবে? আমরা অবশ্যই চাই যে ফলস্বরূপ গাছটি আমরা মুছে ফেলা একটির মতোই হোক। আমরা এটি সহজেই প্রকাশ করতে পারি:

p_delete_nonexistant = forAll aTree (\t ->
                          forAll arbitrary (\k -> 
                              k `notElem` keys t ==> delete t k == t))

এইভাবে, পরীক্ষা করা সত্যিই মজাদার। এবং তদ্ব্যতীত, একবার আপনি চেক চেক বৈশিষ্ট্যগুলি পড়তে শিখলে, তারা মেশিন টেস্টেবল স্পেসিফিকেশন হিসাবে পরিবেশন করে ।


4

"গাণিতিক আইনের মাধ্যমে সংশ্লেষ অর্জন" এর মাধ্যমে সংযুক্ত উত্তরের অর্থ আমি ঠিক বুঝতে পারি না, তবে আমি মনে করি এর অর্থ কী তা সম্পর্কে আমার ধারণা আছে।

ফ্যাক্টর পরীক্ষা করে দেখুন :

ফান্টেক্টর শ্রেণিটি এভাবে সংজ্ঞায়িত করা হয়:

 class Functor f where
   fmap :: (a -> b) -> f a -> f b

এটি পরীক্ষার মামলাগুলির সাথে আসে না, বরং বেশ কয়েকটি আইন নিয়ে সন্তুষ্ট হতে হবে।

ফান্টারের সমস্ত দৃষ্টান্ত অনুসরণ করা উচিত:

 fmap id = id
 fmap (p . q) = (fmap p) . (fmap q)

এখন বলি আপনি বাস্তবায়ন করেছেন Functor( উত্স ):

instance  Functor Maybe  where
    fmap _ Nothing       = Nothing
    fmap f (Just a)      = Just (f a)

আপনার বাস্তবায়ন আইনগুলি সন্তুষ্ট করে তা যাচাই করা সমস্যা। কীভাবে আপনি এটি করতে যান?

একটি পদ্ধতির পরীক্ষার কেস লিখতে হয়। এই পদ্ধতির মৌলিক সীমাবদ্ধতা হ'ল আপনি সীমাবদ্ধ সংখ্যক ক্ষেত্রে আচরণটি যাচাই করছেন (শুভকামনা 8 প্যারামিটারের সাথে একটি ফাংশনটি নিরীক্ষণভাবে পরীক্ষা করছেন!) এবং সুতরাং পরীক্ষাগুলি পাস করার ফলে পরীক্ষাগুলি পাস হওয়ার পরিবর্তে কিছুই গ্যারান্টি দিতে পারে না।

আর একটি পদ্ধতি হ'ল গাণিতিক যুক্তি ব্যবহার করা, অর্থাত্ একটি প্রমাণ, প্রকৃত সংজ্ঞার ভিত্তিতে (সীমিত সংখ্যক ক্ষেত্রে আচরণের পরিবর্তে)। এখানে ধারণাটি একটি গাণিতিক প্রমাণ আরও কার্যকর হতে পারে; যাইহোক, এটি আপনার প্রোগ্রামটি গাণিতিক প্রমাণের জন্য কতটা সম্ভবযোগ্য on

উপরোক্ত Functorউদাহরণ আইনগুলি সন্তুষ্ট করে এমন সত্যিকারের আনুষ্ঠানিক প্রমাণের মাধ্যমে আমি আপনাকে গাইড করতে পারি না , তবে আমি চেষ্টা করব এবং প্রমাণটি কেমন দেখাচ্ছে তার একটি রূপরেখা দেব:

  1. fmap id = id
    • যদি আমাদের থাকে Nothing
      • fmap id Nothing= Nothingবাস্তবায়ন অংশ 1 দ্বারা
      • id Nothing= Nothingসংজ্ঞা দ্বারাid
    • যদি আমাদের থাকে Just x
      • fmap id (Just x)= Just (id x)= Just xবাস্তবায়ন অংশ 2 দ্বারা, তারপরে সংজ্ঞা দ্বারাid
  2. fmap (p . q) = (fmap p) . (fmap q)
    • যদি আমাদের থাকে Nothing
      • fmap (p . q) Nothing= Nothingঅংশ 1 দ্বারা
      • (fmap p) . (fmap q) $ Nothing= (fmap p) $ Nothing= Nothingঅংশ 1 এর দুটি অ্যাপ্লিকেশন দ্বারা
    • যদি আমাদের থাকে Just x
      • fmap (p . q) (Just x)= Just ((p . q) x)= Just (p (q x))পার্ট 2 দ্বারা, তারপরে সংজ্ঞা অনুসারে.
      • (fmap p) . (fmap q) $ (Just x)= (fmap p) $ (Just (q x))= Just (p (q x))পার্ট টু এর দুটি অ্যাপ্লিকেশন দ্বারা

-1

"উপরের কোডে বাগগুলি সম্পর্কে সাবধান থাকুন; আমি কেবল এটি সঠিক প্রমাণ করেছি, এটি চেষ্টা করে দেখিনি।" - ডোনাল্ড নুথ

নিখুঁত বিশ্বে প্রোগ্রামাররা নিখুঁত এবং ভুল করবেন না, তাই কোনও বাগ নেই।

নিখুঁত বিশ্বে কম্পিউটার বিজ্ঞানী এবং গণিতবিদরাও নিখুঁত, এবং ভুলও করবেন না।

তবে আমরা নিখুঁত বিশ্বে বাস করি না। সুতরাং আমরা কোনও ভুল না করার জন্য প্রোগ্রামারদের উপর নির্ভর করতে পারি না। তবে আমরা ধরে নিতে পারি না যে কোনও কম্পিউটার বিজ্ঞানী যে কোনও গাণিতিক প্রমাণ সরবরাহ করেছেন যে কোনও প্রোগ্রাম সঠিক, সে প্রমাণটিতে কোনও ভুল করেন নি। সুতরাং আমি তার কোডটি কাজ করে প্রমাণ করার চেষ্টা করে এমন কারও দিকে কোনও মনোযোগ দেব না । ইউনিট-পরীক্ষা লিখুন এবং আমাকে দেখান যে কোডটি স্পেসিফিকেশন অনুযায়ী আচরণ করে। অন্য যে কোনও কিছু আমাকে কোনও কিছুতেই বিশ্বাস করবে না।


5
ইউনিট পরীক্ষায় ভুলও হতে পারে। আরও গুরুত্বপূর্ণ, পরীক্ষাগুলি কেবল বাগের উপস্থিতি প্রদর্শন করতে পারে - কখনও তাদের অনুপস্থিতি। @ ইঙ্গো যেমন তার উত্তরে বলেছিল, তারা দুর্দান্ত বিচক্ষণতা যাচাই করে এবং ভালভাবে প্রমাণ সরবরাহ করে তবে তারা তাদের প্রতিস্থাপন নয়।
ডোভাল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.