ব্যবহার থেকে বাইন্ডারগুলির জন্য কোনও কার্যের সাথে সীমাবদ্ধ ভেরিয়েবলগুলি উপস্থাপন করা


11

সিনট্যাক্সে বাউন্ডেড ভেরিয়েবলের প্রতিনিধিত্ব করার সমস্যা এবং বিশেষত ক্যাপচার-এড়ানোর বিকল্পের বিষয়টি সুপরিচিত এবং এর বেশ কয়েকটি সমাধান রয়েছে: আলফা-সমতা, ডি ব্রুইজন সূচক, স্থানীয় নামহীনতা, নামমাত্র সেট ইত্যাদির সাথে নামযুক্ত ভেরিয়েবল named

তবে আরও একটি স্পষ্টরূপে দৃষ্টিভঙ্গি উপস্থিত হতে পারে, যা আমি তবুও কোথাও ব্যবহার করতে দেখিনি। যথা, বেসিক সিনট্যাক্সে আমাদের কেবল একটি "ভেরিয়েবল" শব্দ রয়েছে, লিখিত বলুন , এবং তারপরে পৃথকভাবে আমরা একটি ফাংশন দেই যা প্রতিটি ভেরিয়েবলকে একটি বাইন্ডারে মানচিত্র করে যার স্কোপটি এটি থাকে। সুতরাং একটি ল্যাম্বদা-মধ্যম মতλλ

λএক্স(λYএক্সY)

লেখা হবে , এবং ফাংশন প্রথম মানচিত্র হবে প্রথম এবং দ্বিতীয় দ্বিতীয় । সুতরাং ডি Bruijn মত সূচকের এটা ধরনের, শুধুমাত্র পরিবর্তে হচ্ছে "গণনা s" এর সঙ্গতিপূর্ণ দপ্তরী এটি মেয়াদের বাইরে ফিরে হিসাবে, আপনি শুধু একটি ফাংশন নির্ণয় করা। (যদি এটি প্রয়োগের ক্ষেত্রে ডেটা স্ট্রাকচার হিসাবে উপস্থাপন করা হয় তবে আমি প্রতিটি চলক-মেয়াদী অবজেক্টকে সংশ্লিষ্ট বাইন্ডার-টার্ম অবজেক্টের একটি সাধারণ পয়েন্টার / রেফারেন্স সহ সজ্জিত করার কথা ভাবব))λ λ λ λλ(λ)λλλ

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

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


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

এই পদ্ধতির উচ্চতর-আদেশ বিমূর্ত সিনট্যাক্সের সমান নয় (যেমন, হোস্ট ভাষায় বাইন্ডারগুলি ফাংশন হিসাবে উপস্থাপন করে)? এক অর্থে, বাইন্ডার হিসাবে কোনও ফাংশন ব্যবহার করা বন্ধের প্রতিনিধিত্ব করে, বাইন্ডারগুলিকে সুস্পষ্টভাবে পয়েন্টার স্থাপন করে।
রডল্ফ লেপিগ্রে

2
পুনঃটুইট বিশেষত, আমার বোধগম্যতা হল যে এইচওএএস কেবল তখনই সঠিক যখন মেটাথেরি মোটামুটি দুর্বল হয়, তবে এই পদ্ধতিটি একটি স্বেচ্ছাচারিত মেটাথেরিতে সঠিক।
মাইক শুলম্যান

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

3
@ ড্যানডোয়েল আহ, আকর্ষণীয়। আমি ভেবেছিলাম এটি এতটা সুস্পষ্ট যে এটি উল্লেখ করার দরকার নেই যে আপনি শব্দটির পৃথক প্রতিলিপি প্রতিস্থাপিত হওয়ার পরিবর্তে প্রতিবারের পরিবর্তে প্রতিস্থাপিত হবেন; নইলে আপনার আর সিনট্যাক্স গাছ আর থাকত না ! এই অনুলিপিটিকে আলফা-নামকরণ হিসাবে ভাবা আমার পক্ষে ঘটেনি, তবে এখন আপনি এটি উল্লেখ করেছেন আমি এটি দেখতে পাচ্ছি।
মাইক শুলম্যান

উত্তর:


11

আন্ড্রেজের এবং লুকাসের উত্তরগুলি ভাল পয়েন্ট দেয় তবে আমি অতিরিক্ত মন্তব্য যুক্ত করতে চেয়েছিলাম।

দামিয়ানো যা বলেছিল তা প্রতিধ্বনিত করার জন্য, পয়েন্টার ব্যবহার করে বাইন্ডিং উপস্থাপনের এই উপায়টি প্রুফ-নেট দ্বারা প্রস্তাবিত একটি, তবে লাম্বদার শর্তগুলির জন্য আমি এটি প্রথম দিকে যেখানে নুথের একটি পুরানো রচনাটি লিখেছিলাম:

  • ডোনাল্ড নুথ (1970)। আনুষ্ঠানিক শব্দার্থবিদ্যা উদাহরণ। ইন সিম্পোজিয়াম উপর আলগোরিদিমজাত ভাষা শব্দার্থিক , ই Engeler (ইডি।), গণিত 188, স্প্রিনজার মধ্যে বক্তৃতা নোট।

পৃষ্ঠায় 234, তিনি নিম্নলিখিত চিত্রটি আঁকেন (যাকে তিনি "তথ্য কাঠামো" বলেছিলেন) শব্দটির প্রতিনিধিত্ব করে :(λYλz- রYz- র)এক্স

Kn (\ ল্যাম্বদা y। Mb ল্যাম্বদা z.yz) x এর জন্য নুথের চিত্র

এই ধরনের ল্যাম্বডা পদগুলির গ্রাফিকাল উপস্থাপনাটি ১৯ 1970০ এর দশকের গোড়ার দিকে দুটি থিসে স্বতন্ত্রভাবে (এবং আরও গভীরভাবে) অধ্যয়ন করা হয়েছিল, উভয়ই ক্রিস্টোফার ওয়েডসওয়ার্থ (১৯ 1971১, ল্যাম্বডা-ক্যালকুলাসের সিমানটিকস এবং প্রাগেম্যাটিকস ) এবং রিচার্ড স্ট্যাটম্যান (১৯4৪, স্ট্রাকচারাল কমপ্লেক্স िटी) দ্বারা প্রুফ এর )। আজকাল, এই জাতীয় চিত্রগুলি প্রায়শই "graph-গ্রাফ" হিসাবে উল্লেখ করা হয় (উদাহরণস্বরূপ এই কাগজটি দেখুন )।

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

অন্যদিকে, লিনিয়ার পদগুলির জন্য আমি মনে করি এটি দুর্দান্ত! রৈখিকতা precludes অনুলিপি করার জন্য প্রয়োজন নেই, এবং যাতে আপনি উভয় পেতে -equivalence এবং "বিনামূল্যে জন্য" প্রতিকল্পন। এই HOAS হিসাবে একই সুবিধা, এবং আমি প্রকৃতপক্ষে রডল্ফ লেপগ্রির সাথে একমত যে দুটি উপস্থাপনের মধ্যে একটি সংযোগ রয়েছে (যদি ঠিক তেমন কোনও সমতা হয় না): এমন একটি ধারণা রয়েছে যাতে এই গ্রাফিকাল কাঠামোগুলি স্ট্রিং ডায়াগ্রাম হিসাবে প্রাকৃতিকভাবে ব্যাখ্যা করা যেতে পারে , একটি কমপ্যাক্ট বদ্ধ দ্বিধাগ্রীতে একটি প্রতিচ্ছবি বস্তুর endomorphism উপস্থাপন (আমি এখানে একটি সংক্ষিপ্ত ব্যাখ্যা দিয়েছি )।α


10

আমি নিশ্চিত নই যে আপনার পরিবর্তনশীল থেকে বাইন্ডার-ফাংশনটি কীভাবে উপস্থাপিত হবে এবং আপনি কী উদ্দেশ্যে এটি ব্যবহার করতে চান। আপনি যদি ব্যাক-পয়েন্টার ব্যবহার করেন তবে আন্ড্রেজ যেমন উল্লেখ করেছেন যে প্রতিস্থাপনের গণনামূলক জটিলতা শাস্ত্রীয় আলফা-নামকরণের চেয়ে ভাল নয়।

আন্দ্রেজের উত্তর সম্পর্কে আপনার মন্তব্য থেকে আমি অনুমান করি যে আপনি কিছুটা ভাগ করতে আগ্রহী। আমি এখানে কিছু ইনপুট সরবরাহ করতে পারি।

একটি সাধারণ টাইপযুক্ত ল্যাম্বদা ক্যালকুলাসে, অন্য নিয়মের বিপরীতে দুর্বল এবং সংকোচনের সিনট্যাক্স নেই।

Γটি:টিΓ,এক্স:একজনটি:টিওয়াট
Γ,এক্স1:একজন,এক্স2:একজনটি:টিΓ,এক্স:একজনটি:টিসি

আসুন কিছু বাক্য গঠন যুক্ত করুন:

Γটি:টিΓ,এক্স:একজনওয়াটএক্স(টি):টিওয়াট
Γ,এক্স1:একজন,এক্স2:একজনটি:টিΓ,এক্স:একজনসিএক্সএক্স1,এক্স2(টি):টিসি

সিএকটি,()একটি,

সেই সিনট্যাক্সের সাহায্যে প্রতিটি পরিবর্তনশীল ঠিক দু'বার ব্যবহার করা হয়, একবার এটি আবদ্ধ এবং একবার যেখানে এটি ব্যবহৃত হয়। এটি আমাদেরকে একটি নির্দিষ্ট বাক্য গঠন থেকে নিজেকে দূরে রাখতে এবং শব্দটিকে গ্রাফ হিসাবে দেখতে দেয় যেখানে ভেরিয়েবল এবং পদগুলি প্রান্ত হয়।

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

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

এটি ইন্টারঅ্যাকশন নেট, ইন্টারঅ্যাকশন সমন্বয়কারী, সুস্পষ্ট প্রতিস্থাপন, লিনিয়ার লজিক, ল্যাম্পিংয়ের সর্বোত্তম মূল্যায়ন, ভাগ করার গ্রাফ, হালকা লজিক এবং অন্যান্য বিষয়গুলির কাছাকাছি চলেছে।

এই সমস্ত বিষয় আমার জন্য খুব উত্তেজনাপূর্ণ এবং আমি সানন্দে আরও নির্দিষ্ট রেফারেন্স দেব তবে এগুলির কোনওটি আপনার পক্ষে কার্যকর এবং আপনার আগ্রহগুলি কী তা নিশ্চিত আমি নিশ্চিত নই।


6

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

তবে আমি একটি পরীক্ষা দেখে আনন্দিত হব! আপনি lambdaএটি আপনার ডেটা-কাঠামো দিয়ে নিতে এবং প্রয়োগ করতে পারেন (ওক্যামেলের পয়েন্টার রয়েছে, তাদের রেফারেন্স বলা হয় )। বেশী বা কম, আপনি শুধু প্রতিস্থাপন আছে syntax.mlএবং norm.mlআপনার সংস্করণের সাথে। এটি কোডের 150 লাইনের কম।


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

β(λএক্স1)212

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

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

@ মাইকশুলম্যান যুক্তিসঙ্গত (প্রাথমিক) জটিলতার অ্যালগরিদমগুলির জন্য (প্রচুর পরিমাণে অনুলিপি এবং মুছে ফেলার জন্য), ল্যাম্পিংয়ের অনুকূল হ্রাসের তথাকথিত 'অ্যাবস্ট্রাক্ট অংশ' প্রয়োজন পর্যন্ত অনুলিপি তৈরি করছেন না। বিমূর্ত অংশটি সম্পূর্ণ অ্যালগরিদমের বিপরীতে অ-বিতর্কিত অংশও যার জন্য কয়েকটি টিকা প্রয়োজন যা গণনাতে আধিপত্য করতে পারে।
asukasz Lew

5

অন্যান্য উত্তরগুলি বেশিরভাগ বাস্তবায়নের সমস্যাগুলি নিয়ে আলোচনা করে। যেহেতু আপনি আপনার মূল অনুপ্রেরণাকে খুব বেশি হিসাবরক্ষণ ছাড়াই গাণিতিক প্রমাণগুলি হিসাবে উল্লেখ করেছেন, তাই আমি এখানে এটিই দেখছি মূল বিষয়টি।

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

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

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


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

(সম্মত হয়েছি যে এটি চেষ্টা করার মতো মূল্য ... যদিও ইতিমধ্যে কারও কাছে প্রুফ-নেট /
graph-


5

λLazy.t

সামগ্রিকভাবে, আমি মনে করি এটি একটি দুর্দান্ত উপস্থাপনা, তবে এতে বাইন্ডিং লিঙ্কগুলি ভঙ্গ করতে এড়াতে পয়েন্টারগুলির সাথে কিছু বুককিপিং জড়িত। আমার ধারণা অনুসারে পরিবর্তনীয় ক্ষেত্রগুলি ব্যবহার করার জন্য কোডটি পরিবর্তন করা সম্ভব হবে তবে কোকের মধ্যে এনকোডিং কম সরাসরি হবে। আমি এখনও নিশ্চিত যে এটি HOAS এর সাথে খুব মিল, যদিও পয়েন্টার কাঠামোটি স্পষ্ট করে দেওয়া হয়েছে। যাইহোক, উপস্থিতি থেকে Lazy.tবোঝা যায় যে কোনও কোডের জন্য ভুল সময়ে মূল্যায়ন করা সম্ভব। আমার কোডে এটি হয় না কারণ ভেরিয়েবলের সাথে কেবলমাত্র একটি চলকের বিকল্প প্রতিস্থাপন সময়ে ঘটতে পারে force(এবং উদাহরণের জন্য মূল্যায়ন নয়)।

(* Representation of a term of the λ-calculus. *)
type term =
  | FVar of string      (* Free variable  *)
  | BVar of bvar        (* Bound variable *)
  | Appl of term * term (* Application    *)
  | Abst of abst        (* Abstraction    *)

(* A bound variable is a pointer to the corresponding binder. *)
and bvar = abst

(* A binder is represented as its body in which the bound variable points to
   the binder itself. Note that we need to use a thunk to be able to work
   underneath a binder (for substitution, evaluation, ...). A name can be
   given for easy printing, but no renaming is done. Only “visual capture”
   can happen since pointers are established the right way, even if names
   can clash. *)
and abst = { body : term Lazy.t ; name : string }

(* Terms can be built with recursive values for abstractions. *)

(* Krivine's notation is used for application (function in parentheses). *)

let id    : term = (* λx.x        *)
  Abst(let rec id = {body = lazy (BVar(id)); name = "x"} in id)

let idid  : term = (* (λx.x) λx.x *)
  Appl(id, id)

let delta : term = (* λx.(x) x *)
  Abst(let rec d = {body = lazy (Appl(BVar(d), BVar(d))); name = "x" } in d)

let weird : term = (* (λx.x) λy.(λx.(x) x) (C) y *)
  Appl(id, Abst(let rec x = {body = lazy (Appl(delta, Appl(FVar("C"),
    BVar(x)))); name = "y"} in x))

let omega : term = (* (λx.(x) x) λx.(x) x *)
  Appl(delta, delta)

(* Printing function is immediate. *)
let rec print : out_channel -> term -> unit = fun oc t ->
  match t with
  | FVar(x)   -> output_string oc x
  | BVar(x)   -> output_string oc x.name
  | Appl(t,u) -> Printf.fprintf oc "(%a) %a" print t print u
  | Abst(f)   -> Printf.fprintf oc "λ%s.%a" f.name print (Lazy.force f.body)

(* Substitution of variable [x] by [v] in the term [t]. Occurences of [x] in
   [t] are identified using physical equality ([BVar] case). The subtle case
   is [Abst], because we need to reestablish the physical link between the
   binder and the variable it binds. *)
let rec subst_var : bvar -> term -> term -> term = fun x t v ->
  match t with
  | FVar(_)   -> t
  | BVar(y)   -> if y == x then v else t
  | Appl(t,u) -> Appl(subst_var x t v, subst_var x u v)
  | Abst(f)   ->
      (* First compute the new body. *)
      let fv = subst_var x (Lazy.force f.body) v in
      (* Reestablish the physical link, using [subst_var] itself again. This
         requires a second traversal of the term. We could probably do both
         at once, but who cares the complexity is linear in [t] anyway. *)
      Abst(let rec g = {f with body = lazy (subst_var f fv (BVar(g)))} in g)

(* Actual substitution function. *)
let subst : abst -> term -> term = fun f v ->
  subst_var f (Lazy.force f.body) v

(* Normalization function (all the way, even under binders). *)
let rec eval : term -> term = fun t ->
  match t with
  | Appl(t,u) ->
      begin
        let v = eval u in
        match eval t with
        | Abst(f) -> eval (subst f v)
        | t       -> Appl(t,v)
      end
  | Abst(f)   ->
      (* Actual computation in the body. *)
      let fv = eval (Lazy.force f.body) in
      (* Here, the physical link is reestablished, but it is important to note
         that the computation of evaluation is done above. So the part below
         only takes a linear time in the size of the normal form of the body
         of the abstraction. *)
      Abst(let rec g = {f with body = lazy (subst_var f fv (BVar(g)))} in g)
  | _         ->
      t

let _ = Printf.printf "id         = %a\n%!" print id
let _ = Printf.printf "eval id    = %a\n%!" print (eval id)

let _ = Printf.printf "idid       = %a\n%!" print idid
let _ = Printf.printf "eval idid  = %a\n%!" print (eval idid)

let _ = Printf.printf "delta      = %a\n%!" print delta
let _ = Printf.printf "eval delta = %a\n%!" print (eval delta)

let _ = Printf.printf "omega      = %a\n%!" print omega
(* The following obviously loops. *)
(*let _ = Printf.printf "eval omega = %a\n%!" print (eval omega)*)

let _ = Printf.printf "weird      = %a\n%!" print weird
let _ = Printf.printf "eval weird = %a\n%!" print (eval weird)

(* Output produced:
id         = λx.x
eval id    = λx.x
idid       = (λx.x) λx.x
eval idid  = λx.x
delta      = λx.(x) x
eval delta = λx.(x) x
omega      = (λx.(x) x) λx.(x) x
weird      = (λx.x) λy.(λx.(x) x) (C) y
eval weird = λy.((C) y) (C) y
*)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.