নেস্টেড উপাদানগুলির সাথে একটি ইন্ডাকটিভ টাইপের উপরে পুনরাবৃত্ত সংজ্ঞা


21

একটি উদ্রেককারী ধরণের বিবেচনা করুন যা নেস্টেড, তবে কঠোরভাবে ইতিবাচক স্থানে কিছু পুনরাবৃত্ত ঘটনা রয়েছে। উদাহরণস্বরূপ, নোডগুলির সাথে সসীম শাখাযুক্ত গাছ বাচ্চাদের সঞ্চয় করার জন্য জেনেরিক তালিকা ডেটা কাঠামো ব্যবহার করে।

Inductive LTree : Set := Node : list LTree -> LTree.

গাছগুলি এবং গাছের তালিকাগুলির উপরে পুনরাবৃত্তি করে এই গাছগুলির উপর পুনরাবৃত্ত ক্রিয়াকলাপ সংজ্ঞায়িত করার সহজ উপায় কাজ করে না। sizeনোডগুলির সংখ্যা গণনা করে এমন ফাংশনটির সাথে এখানে একটি উদাহরণ রয়েছে ।

Fixpoint size (t : LTree) : nat := match t with Node l => 1 + (size_l l) end
with size_l (l : list LTree) : nat := match l with
    | nil => 0
    | cons h r => size h + size_l r
  end.

এই সংজ্ঞাটি অ-গঠিত (ত্রুটির বার্তাটি উদ্ধৃত):

Error:
Recursive definition of size_l is ill-formed.
Recursive call to size has principal argument equal to
"h" instead of "r".

সংজ্ঞাটি কেন খারাপভাবে গঠিত, যদিও rএটি স্পষ্টভাবে একটি subterm l? এই জাতীয় ডেটা স্ট্রাকচারে পুনরাবৃত্ত ফাংশন সংজ্ঞায়নের কোনও উপায় আছে কি?


আপনি যদি কাক সিনট্যাক্সে সাবলীল না হন: LTreeনিম্নলিখিত ব্যাকরণের সাথে সম্পর্কিত একটি প্ররোচিত ধরনের।

LTree::=|list(LTree)

আমরা sizeগাছ এবং তালিকাগুলি অন্তর্ভুক্ত করে ফাংশনটি সংজ্ঞায়িত করার চেষ্টা করি । ওক্যামেলে, এটি হবে:

type t = Node of t list
let rec size = function Node l -> 1 + size_l l
and size_l = function [] -> 0
                    | h::r -> size h + size_l r

এটি কি অন-টপিক? আমি নিশ্চিত নই; এর মেটায় আলোচনা করা যাক
গিলস

আপনি কি কম কোকি এবং আরও বেশি ম্যাথিতে সমতুল্য ফাংশন সংজ্ঞা যুক্ত করতে পারেন? সিনট্যাক্স বুঝতে আমার সমস্যা হচ্ছে।
রাফেল

1
@ রাফেল আমি চেষ্টা করেছি, এখন কি এটি আরও ভাল? সত্যিই, এই প্রশ্নটি কোকের পক্ষে বেশ নির্দিষ্ট।
গিলস

উত্তর:


14

কি কাজ

আপনি যদি গাছের উপরে ফিক্সপয়েন্টের সংজ্ঞাটির ভিতরে তালিকাগুলিতে ফিক্সপয়েন্টের সংজ্ঞাটি বাসা করেন তবে ফলাফলটি ভাল টাইপ করা হয়। এটি একটি সাধারণ নীতি যখন আপনি একটি प्रेरক ধরণের পুনরাবৃত্তি নেস্ট করে থাকেন, অর্থাত্ যখন পুনরাবৃত্তি যেমন কোনও নির্মাণকারীর মধ্য দিয়ে যায় list

Fixpoint size (t : LTree) : nat :=
  let size_l := (fix size_l (l : list LTree) : nat :=
                  match l with
                    | nil => 0
                    | h::r => size h + size_l r
                  end) in
  match t with Node l =>
    1 + size_l l
  end.

অথবা আপনি যদি আরও নিখুঁতভাবে লিখতে পছন্দ করেন:

Fixpoint size (t : LTree) : nat :=
  match t with Node l =>
    1 + (fix size_l (l : list LTree) : nat :=
          match l with
            | nil => 0
            | h::r => size h + size_l r
          end) l
  end.

(আমি প্রথম থেকে কে শুনেছি তা আমার কোনও ধারণা নেই; এটি অবশ্যই অনেকবার স্বাধীনভাবে আবিষ্কার হয়েছিল))

একটি সাধারণ পুনরাবৃত্তি ভবিষ্যদ্বাণী

আরও সাধারণভাবে, আপনি LTreeম্যানুয়ালি "যথাযথ" আনয়ন নীতিটি সংজ্ঞায়িত করতে পারেন । স্বয়ংক্রিয়ভাবে উত্পন্ন উত্সাহ নীতি LTree_rectতালিকায় অনুমানটি বাদ দেয় কারণ আবেশন নীতি জেনারেটর কেবল ইনডাকটিভ টাইপের অ-নেস্টেড কঠোরভাবে ইতিবাচক ঘটনাগুলি বোঝে।

LTree_rect = 
fun (P : LTree -> Type) (f : forall l : list LTree, P (Node l)) (l : LTree) =>
match l as l0 return (P l0) with
| Node x => f x
end
     : forall P : LTree -> Type,
       (forall l : list LTree, P (Node l)) -> forall l : LTree, P l

আসুন তালিকাতে আবেশ অনুমান যুক্ত করুন। পুনরাবৃত্তির কলটিতে এটি সম্পাদন করার জন্য, আমরা তালিকাটি অন্তর্ভুক্তির নীতিটি কল করি এবং এটিকে তালিকার অভ্যন্তরে ছোট গাছের উপর বৃক্ষ আনয়ন নীতিটি পাস করি।

Fixpoint LTree_rect_nest (P : LTree -> Type) (Q : list LTree -> Type)
                         (f : forall l, Q l -> P (Node l))
                         (g : Q nil) (h : forall t l, P t -> Q l -> Q (cons t l))
                         (t : LTree) :=
  match t as t0 return (P t0) with
    | Node l => f l (list_rect Q g (fun u r => h u r (LTree_rect_nest P Q f g h u)) l)
  end.

কেন

পুনরাবৃত্ত ক্রিয়াকলাপ গ্রহণের জন্য সঠিক নিয়মে কেন এই উত্তর। এই নিয়মগুলি পারফরম্যান্স সূক্ষ্ম, কারণ জটিল কেসগুলি (যেমন এটি যেমন ডেটাটাইপে নেস্টেড পুনরাবৃত্তি সহ) এবং আনসোসনেসনের মধ্যে একটি সূক্ষ্ম ভারসাম্য রয়েছে। Coq সহায়িকা প্রবর্তন ভাষা (প্রস্তাবনামূলক বাক্য এর ক্যালকুলাস, যা Coq প্রমাণ ভাষা), বেশিরভাগ আনুষ্ঠানিকভাবে সুনির্দিষ্ট সংজ্ঞা সঙ্গে, কিন্তু আপনি আনয়ন এবং coinduction আপনার যা দরকার গবেষণা কাগজপত্র যাব সংক্রান্ত সঠিক নিয়ম চান, এই বিষয়টিতে এডুয়ার্ডো গিমেনেজের [1]।

কোক ম্যানুয়াল দিয়ে শুরু করে, Fixনিয়মের স্বরলিপি হিসাবে , আমাদের এর ফিক্সপয়েন্ট সংজ্ঞা রয়েছেFixfi{f1:A1:=t1;f2:A2:=t2}

Γ1=(x:LTree)A1=natt1=case(x,LTree,λy.g1(f2y))Γ2=(l:listLTree)A2=natt2=case(l,listLTree,λhr.g2(f1h)(f2r))

fjtifi

  • i=1j=2ltsize
  • i=2j=1hlsize_l
  • i=2j=2rlsize_l

কোক ইন্টারপ্রেটারের hচেয়ে কাঠামোগতভাবে ছোট না হওয়ার কারণটি lআমার কাছে পরিষ্কার নয়। কোক-ক্লাবের তালিকার [১] [২] আলোচনা থেকে আমি যতদূর বুঝতে পেরেছি, এটি দোভাষীর ক্ষেত্রে একটি বিধিনিষেধ, যা নীতিগতভাবে উঠানো যেতে পারে, তবে খুব সতর্কতার সাথে কোনও অসঙ্গতি না এড়াতে।

তথ্যসূত্র

কোকোরিকো, অবিচ্ছিন্ন কোক উইকি: মিউচুয়াল আনয়ন

কোক-ক্লাবের মেইলিং তালিকা:

কক উন্নয়ন দল। কক প্রুফ সহকারী: রেফারেন্স ম্যানুয়াল । সংস্করণ 8.3 (2010)। [ ওয়েব ] সিএইচ। ঘ

এডুয়ার্ডো গিমেনেজ রিকার্সিভ স্কিম সঙ্গে পাহারায় সংজ্ঞা Codifying । ইন Types'94: প্রমাণের প্রোগ্রামের জন্য প্রকারভেদ , LNCS 996. স্প্রিঙ্গের-ভার্ল্যাগ, 1994 ডোই: 10.1007 / 3-540-60579-7_3 [ স্প্রিঙ্গের ]

এডুয়ার্ডো গিমেনেজ টাইপ থিওরিতে স্ট্রাকচারাল রিকার্সিভ সংজ্ঞা । ইন ICALP'98: 25th অটোমাটা, ভাষা এবং প্রোগ্রামিং এর উপর আন্তর্জাতিক colloquium প্রসিডিংস। স্প্রিঞ্জার-ভার্লাগ, 1998 [[ পিডিএফ ]


7

এটি অবশ্যই কোকের জন্য নির্দিষ্ট সমস্যা, কারণ আমি বিশ্বাস করি যে আরও কিছু প্রুফ অ্যাসিস্ট্যান্ট (আমি আগদার দিকে তাকিয়ে আছি) এর সাথে আশেপাশের আরও ভাল উপায় রয়েছে believe

প্রথমে আমি ভেবেছিলাম rকাঠামোগতভাবে ছোট হিসাবে স্বীকৃতি পাওয়া যায় নি কারণ কাঠামোটি কেবলমাত্র বর্তমান দ্বারা পরিচালিত ইনডাকটিভ সংজ্ঞা সম্পর্কে Fixpoint: সুতরাং এটি একটি LTreesubterm হলেও এটি একটি listsubterm নয়।

তবে আপনি যদি তালিকার প্রসেসিং প্রসারিত করেন তবে তা কাজ করে:

Fixpoint size t :=
  match t with
  | Node l => S
     ((fix size_l l :=
     match l with
     | nil => 0
     | cons t l => size_l l + size t
     end) l)
 end.

বা স্ট্যান্ডার্ড লাইব্রেরিতে সহায়ক ফাংশন ইতিমধ্যে বিদ্যমান রয়েছে:

Require Import List.

Fixpoint size t :=
  match t with
  | Node l => S (fold_left (fun a t => a + size t) l 0)
  end.

সত্যি কথা বলতে কি আমি নিশ্চিত নই যে এগুলি কক গ্রহণ করেছে কেন, তবে তারা নিশ্চিত যে আমি নিশ্চিত।

একটি সমাধান রয়েছে যা আরও প্রায়শই কাজ করে এবং কেবল তালিকাগুলির জন্য নয়: একটি স্ব-অন্তর্ভুক্ত ইন্ডাকটিভ টাইপের সংজ্ঞা দেওয়া। এই ক্ষেত্রে আপনি নিজের sizeফাংশনটি ম্যানুয়ালি সংজ্ঞায়িত করতে পারেন । (দুটি ফিক্সপয়েন্ট সহ)

Inductive LTree : Set :=
  | Node : list_LTree -> LTree
with list_LTree : Set :=
  | LTree_nil : list_LTree
  | LTree_cons : LTree -> list_LTree -> list_LTree.

মনে রাখবেন যে আরও জটিল ইন্ডাকটিভ সংজ্ঞাগুলির জন্য আপনার যদি সমস্যা হয় তবে আপনি একটি আকার-হ্রাস যুক্তি ব্যবহার করতে পারেন। এটি সম্ভব তবে এই সমস্যার জন্য জটিল (এবং আমি বেশিরভাগ সমস্যার জন্য বলতে সাহস করব)


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