আপনি যদি ফাংশনের ডোমেনটি গণনা করতে পারেন এবং সাম্যের জন্য সীমার উপাদানগুলির তুলনা করতে পারেন, আপনি - বরং সোজা উপায়ে করতে পারেন। গণনা করার অর্থ আমার কাছে উপলব্ধ সমস্ত উপাদানগুলির একটি তালিকা রয়েছে। আমি হাস্কেলের সাথে লেগে থাকব, যেহেতু আমি ওকামেলকে জানি না (বা কীভাবে এটি সঠিকভাবে মূলধন করা যায় ;-)
আপনি যা করতে চান তা ডোমেনের উপাদানগুলির মাধ্যমে চালিত হয় এবং দেখুন যে সেগুলি আপনি উল্টানোর চেষ্টা করছেন এমন পরিসরের উপাদানটির সাথে সমান কিনা এবং প্রথম যেটি কাজ করে তা গ্রহণ করুন:
inv :: Eq b => [a] -> (a -> b) -> (b -> a)
inv domain f b = head [ a | a <- domain, f a == b ]
যেহেতু আপনি এটি বলেছেন f
এটি একটি হ'ল একটি বাইজেকশন, তাই এখানে কেবলমাত্র একটির মতো উপাদান হতে বাধ্য। কৌশলটি অবশ্যই, তা নিশ্চিত করা হ'ল আপনার ডোমেনের অঙ্কটি একটি নির্দিষ্ট সময়ের মধ্যে সমস্ত উপাদানগুলিতে আসলে পৌঁছেছে । আপনার কাছ থেকে একটি bijection invert করার চেষ্টা করছেন তবে Integer
করতে Integer
ব্যবহার [0,1 ..] ++ [-1,-2 ..]
কাজ না করবে না আপনি ঋণাত্মক সংখ্যার আগে কখনো পাবেন না। কংক্রিটলি, inv ([0,1 ..] ++ [-1,-2 ..]) (+1) (-3)
কখনই কোনও মান দেয় না।
তবে 0 : concatMap (\x -> [x,-x]) [1..]
এটি কাজ করবে, কারণ এটি নিম্নলিখিত ক্রমে পূর্ণসংখ্যার মধ্য দিয়ে চলে [0,1,-1,2,-2,3,-3, and so on]
। প্রকৃতপক্ষে inv (0 : concatMap (\x -> [x,-x]) [1..]) (+1) (-3)
অবিলম্বে ফেরৎ -4
!
Control.Monad.Omega প্যাকেজ সাহায্য করতে পারেন একটি ভাল উপায় tuples ইত্যাদি তালিকা মাধ্যমে চালানো; আমি নিশ্চিত যে এর মতো আরও প্যাকেজ রয়েছে - তবে আমি সেগুলি জানি না।
অবশ্যই, এই পদ্ধতির বদলে কম-ব্রাউড এবং হিংস্র-শক্তি, কুৎসিত এবং অদক্ষতার কথা উল্লেখ না করে! সুতরাং আমি কীভাবে বাইজিকেশন লিখতে পারি সে সম্পর্কে আপনার প্রশ্নের শেষ অংশে কয়েকটি মন্তব্য দিয়ে শেষ করব। হাস্কেলের টাইপ সিস্টেমটি প্রমাণ করে না যে কোনও ফাংশন হ'ল একটি বাইজেকশন - আপনি সত্যিকার অর্থে আগদার মতো কিছু চান - তবে এটি আপনাকে বিশ্বাস করতে ইচ্ছুক।
(সতর্কতা: নিরীক্ষিত কোড অনুসরণ করা হয়েছে)
সুতরাং আপনি Bijection
ধরণের a
এবং এর মধ্যে একটি ডেটাটাইপ সংজ্ঞায়িত করতে পারেন b
:
data Bi a b = Bi {
apply :: a -> b,
invert :: b -> a
}
আপনার পছন্দ মতো আরও অনেকগুলি ধ্রুবক (যেখানে আপনি বলতে পারেন 'আমি জানি তারা বাইজিকেশন!') যেমন:
notBi :: Bi Bool Bool
notBi = Bi not not
add1Bi :: Bi Integer Integer
add1Bi = Bi (+1) (subtract 1)
এবং বেশ কয়েকটি স্মার্ট সংযুক্তকারী, যেমন:
idBi :: Bi a a
idBi = Bi id id
invertBi :: Bi a b -> Bi b a
invertBi (Bi a i) = (Bi i a)
composeBi :: Bi a b -> Bi b c -> Bi a c
composeBi (Bi a1 i1) (Bi a2 i2) = Bi (a2 . a1) (i1 . i2)
mapBi :: Bi a b -> Bi [a] [b]
mapBi (Bi a i) = Bi (map a) (map i)
bruteForceBi :: Eq b => [a] -> (a -> b) -> Bi a b
bruteForceBi domain f = Bi f (inv domain f)
আমি মনে করি আপনি তখন করতে invert (mapBi add1Bi) [1,5,6]
এবং পেতে পারে[0,4,5]
। আপনি যদি আপনার সংযোগকারীকে স্মার্ট উপায়ে বেছে নেন তবে আমি মনে করি যে আপনাকে Bi
হাতে নিয়ে একটি ধ্রুবক লিখতে হবে তার সংখ্যাটি বেশ সীমাবদ্ধ হতে পারে।
সর্বোপরি, যদি আপনি জানেন কোনও ফাংশন হ'ল একটি হস্তক্ষেপ, তবে আপনার কাছে আশাবাদী আপনার মাথার মধ্যে সেই সত্যতার একটি প্রমাণ-স্কেচ থাকবে, যা কারি-হাওয়ার্ড আইসোমরফিজম একটি প্রোগ্রামে পরিণত করতে সক্ষম হবে :-)
f x = 1
1 এর ইনভার্সটি পূর্ণসংখ্যার একটি সেট এবং অন্য কোনও কিছুর বিপরীতটি একটি খালি সেট। কিছু উত্তর যাই বলুক না কেন, দ্বিপক্ষীয় না হওয়াটি ফাংশনটি সবচেয়ে বড় সমস্যা নয়।