খাঁটি কার্যকরী ভাষায়, বিপরীতমুখী ফাংশনটি পাওয়ার জন্য কোনও অ্যালগরিদম আছে কি?


100

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


5
গাণিতিকভাবে এটি বলা ভুল হবে না যে, এর ক্ষেত্রে f x = 11 এর ইনভার্সটি পূর্ণসংখ্যার একটি সেট এবং অন্য কোনও কিছুর বিপরীতটি একটি খালি সেট। কিছু উত্তর যাই বলুক না কেন, দ্বিপক্ষীয় না হওয়াটি ফাংশনটি সবচেয়ে বড় সমস্যা নয়।
ক্যারোলিস জুডেলė

2
সঠিক প্রতিক্রিয়া হ্যাঁ, তবে এটি দক্ষ নয়। চলুন f: A -> B এবং A সসীম, তারপরে, b € B দেওয়া, আপনাকে সমস্ত "only A" এফ (এ) = বি সন্ধানের জন্য সমস্ত চ (এ) পরিদর্শন করতে হবে। কোয়ান্টাম কম্পিউটারে সম্ভবত ও (আকার (ক)) জটিলতা থাকবে। অবশ্যই, আপনি একটি ব্যবহারিক অ্যালগরিদম সন্ধান করুন। এটি (ও (2 ^ আকার (ক) আছে)) নয়, তবে বিদ্যমান ...
জোসেজুয়ান

কুইকচেক এটি হুবহু করছে (তারা এফ: এ -> বুলে একটি মিথ্যা সন্ধান করে)।
জোসেজুয়ান

4
@ কারোলিস জুডেলė: আমি একমত নই; এটি সাধারণত বিপরীত দ্বারা বোঝানো হয় না। আমি যতবার প্রতি শব্দটির মুখোমুখি হই খুব সুন্দর, বিপরীতটি fএকটি ফাংশন gযেমন f . g = idএবং g . f = id। আপনার প্রার্থী সেক্ষেত্রে টাইপচেকও করেন না।
বেন মিলউড

3
@ বেনমিলউড, আপনি ঠিক বলেছেন আমি যা বলেছি তাকে একটি বিপরীত চিত্র বলা হয়, একটি বিপরীত ফাংশন নয়। আমার বক্তব্যটি ছিল যে উত্তরগুলি নির্দেশ করে f x = 1যেগুলির কোনও বিপরীত নেই খুব সংকীর্ণ পদ্ধতির গ্রহণ করে এবং সমস্যার পুরো জটিলতা উপেক্ষা করে।
কারোলিস জুডেলė

উত্তর:


101

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

আপনার ফাংশনটি অবিচ্ছিন্ন হওয়ার ক্ষেত্রে আপনি যা খুঁজে পাবেন তা হ'ল বিপরীত (একটি মজাদার ইনপুট সহ); অন্যান্য ক্ষেত্রে, আপনি একটি ফাংশন পাবেন যা একটি পুরানো ইনপুট মান এবং একটি নতুন আউটপুট মান "মার্জ" করার চেষ্টা করে।


3
এখানে একটি আরও সাম্প্রতিক কাগজ যা দ্বিদ্বিপায়নে শিল্পের স্থিতির জরিপ করে। এটিতে
sclv

এবং কেবল উল্লেখ করার জন্য, ২০০৮-এ ক্যাফেতে এই বার্তাটি ছিল, যে putকোনও রেকর্ড কাঠামোতে ফাংশন ইনভার্ট করার জন্য একটি অশুভ হ্যাক সহ Data: haskell.org/pipermail/haskell-cafe/2008-April/042193.html এর অনুরূপ একটি পন্থা ব্যবহার করে যা পরে "আরও নিখরচায়" আরও কঠোরভাবে, আরও সাধারণভাবে, আরও মূলত, ইত্যাদি) উপস্থাপন করা হয়েছিল।
sclv

এটি 2017 এবং অবশ্যই কাগজের লিঙ্কটি এখানে বৈধ নয় here pdfs.semanticscholar.org/5f0d/…
মিনা গ্যাব্রিয়েল

37

না, এটি সাধারণভাবে সম্ভব নয়।

প্রুফ: দ্বিপাক্ষিক ফাংশন বিবেচনা করুন

type F = [Bit] -> [Bit]

সঙ্গে

data Bit = B0 | B1

ধরে আমরা বৈদ্যুতিন সংকেতের মেরু বদল একটি আছে inv :: F -> Fযেমন যে inv f . f ≡ id। বলুন যে আমরা এটি f = idনিশ্চিত করে ফাংশনের জন্য এটি পরীক্ষা করেছি

inv f (repeat B0) -> (B0 : ls)

যেহেতু B0আউটপুটে এটি প্রথমটি অবশ্যই কিছু সীমাবদ্ধ সময়ের পরে এসেছিল, তাই আমাদের এই ফলাফলটি অর্জনের জন্য আমাদের পরীক্ষার ইনপুটটিকে যে nগভীরতার সাথে invমূল্যায়ন করেছিল, সেই একই সাথে এটি কতবার ডাকতে পারে তার উভয়ই উপরে আমাদের উপরের আবদ্ধ থাকে f। এখন ফাংশনগুলির একটি পরিবার সংজ্ঞা দিন

g j (B1 : B0 : ... (n+j times) ... B0 : ls)
   = B0 : ... (n+j times) ... B0 : B1 : ls
g j (B0 : ... (n+j times) ... B0 : B1 : ls)
   = B1 : B0 : ... (n+j times) ... B0 : ls
g j l = l

স্পষ্টতই, সবার জন্য 0<j≤n, g jএটি একটি বাইজেকশন, বাস্তবে স্ব-বিপরীত। সুতরাং আমরা নিশ্চিত করতে সক্ষম হওয়া উচিত

inv (g j) (replicate (n+j) B0 ++ B1 : repeat B0) -> (B1 : ls)

তবে এটি পূরণ করার জন্য inv (g j)যে কোনও একটির দরকার পড়ে

  • g j (B1 : repeat B0)একটি গভীরতা মূল্যায়নn+j > n
  • head $ g j lকমপক্ষে nবিভিন্ন তালিকার মিলের জন্য মূল্যায়ন করুনreplicate (n+j) B0 ++ B1 : ls

আপ যে বিন্দু থেকে, এর অন্তত একটি g jথেকে আলাদা করা যায় fএবং যেহেতু inv fএই মূল্যায়ন উভয় না করতাম, invসম্ভবত এটা পৃথক্ বলেছি করা যায়নি - নিজস্ব, যা একমাত্র সম্ভব কিছু রানটাইম-পরিমাপ করছেন সংক্ষিপ্ত IO Monad

                                                                                                                                   ⬜


19

আপনি উইকিপিডিয়ায় এটি সন্ধান করতে পারেন, একে রিভার্সিবল কম্পিউটিং বলে

সাধারণভাবে আপনি এটি করতে পারবেন না যদিও এবং কার্যকরী ভাষার কোনওটিরই বিকল্প নেই। উদাহরণ স্বরূপ:

f :: a -> Int
f _ = 1

এই ফাংশনটির কোনও বিপরীত নেই।


1
এটি কি fএকটি বিপরীত আছে বলে ভুল হতে পারে , এটি ঠিক যে বিপরীতটি একটি অ-বিবাদী ফাংশন?
ম্যাট ফেনউইক

10
@ ম্যাটফেনউইক উদাহরণস্বরূপ হাস্কেলের মতো ভাষায়, ফাংশনগুলি কেবল নিরপেক্ষবাদী নয় (প্রকারগুলি এবং আপনি তাদের ব্যবহারের পদ্ধতি পরিবর্তন না করে)। আপনি গাণিতিকভাবে বিপরীতটি বর্ণনা করতে পারলেও এমন কোনও হাস্কেল ফাংশন নেই g :: Int -> aযা fবিপরীত হয় f
বেন

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

2
@ ম্যাট: অ-অস্তিত্বের অ-অস্তিত্বকে অ-নির্ধারণবাদের দিক থেকে চিহ্নিত করার পরিবর্তে, একে একে নীচু পদে চিহ্নিত করতে হবে। F _ = 1 এর বিপরীতমুখীটি নীচে, যেহেতু এটি অবশ্যই প্রতিটি ধরণের বাস করে (বিকল্প হিসাবে, এটি নীচে কারণ কোনও একক উপাদানের চেয়ে কোনও ধরণের বিপরীতমুখী ক্রিয়াকলাপ নেই - আপনি যে দিকটি মনোনিবেশ করেছেন, আমি মনে করি)। নীচে হওয়াকে মান সম্পর্কে দৃser়তা হিসাবে ইতিবাচক এবং নেতিবাচকভাবে নেওয়া যেতে পারে। একটি সংবেদনশীল ফাংশনের বিপরীতটিকে "মান" নীচ হিসাবে বিবেচনা করে সংজ্ঞাগতভাবে বলতে পারেন। (যদিও এটি "সত্যই" একটি মান নয়)
নাম দিন

1
এখানে অনেক পরে ঘোরাফেরা করার পরে, আমি মনে করি আমি ম্যাট কী পাচ্ছে তা দেখতে পাচ্ছি: আমরা প্রায়শই তালিকার মাধ্যমে অদ্বিতীয়তাকে মডেল করি এবং বিপরীতগুলির জন্য আমরাও এটি করতে পারি। বিপরীত যাক f x = 2 * xহতে f' x = [x / 2], এবং তারপর বিপরীত f _ = 1হয় f' 1 = [minBound ..]; f' _ = []। অর্থাৎ, 1 এর জন্য অনেকগুলি বিপরীত রয়েছে এবং অন্য কোনও মানের জন্য কিছুই নেই none
aMLoy

16

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


1
বা বুধ , যা অন্যথায় হাস্কেলের স্পিরিট অনেক ভাগ করে দেয়। - ভাল পয়েন্ট, +1।
9:30 এ বাম দিকের বাইরে

11

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

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

ল্যাম্বডা-শর্তাদির একটি সেট অনন্যতর যদি এটি খালি না হয় বা পুরো সেট না থাকে। যদি এ এবং বি দুটি অযৌক্তিক হয়, (বিটা) সমতার অধীনে বন্ধ ল্যাম্বডা-শর্তগুলির বিচ্ছিন্ন সেটগুলি, তবে এ এবং বি পুনরাবৃত্তভাবে অবিচ্ছেদ্য হয়।

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

(এটি টাইপড ল্যাম্বডা ক্যালকুলাসের ক্ষেত্রে প্রযোজ্য T অনুরূপ.)


11

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

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

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হাতে নিয়ে একটি ধ্রুবক লিখতে হবে তার সংখ্যাটি বেশ সীমাবদ্ধ হতে পারে।

সর্বোপরি, যদি আপনি জানেন কোনও ফাংশন হ'ল একটি হস্তক্ষেপ, তবে আপনার কাছে আশাবাদী আপনার মাথার মধ্যে সেই সত্যতার একটি প্রমাণ-স্কেচ থাকবে, যা কারি-হাওয়ার্ড আইসোমরফিজম একটি প্রোগ্রামে পরিণত করতে সক্ষম হবে :-)


6

আমি সম্প্রতি এই জাতীয় সমস্যাগুলি নিয়ে কাজ করেছি এবং না, আমি বলব যে (ক) এটি অনেক ক্ষেত্রেই কঠিন নয়, তবে (খ) এটি মোটেই দক্ষ নয়।

মূলত, ধরুন আপনার কাছে আছে f :: a -> bএবং এটি fসত্যই বাইজিকেশন। আপনি f' :: b -> aসত্যিই বোবা উপায়ে বিপরীত গণনা করতে পারেন :

import Data.List

-- | Class for types whose values are recursively enumerable.
class Enumerable a where
    -- | Produce the list of all values of type @a@.
    enumerate :: [a]

 -- | Note, this is only guaranteed to terminate if @f@ is a bijection!
invert :: (Enumerable a, Eq b) => (a -> b) -> b -> Maybe a
invert f b = find (\a -> f a == b) enumerate

যদি fকোনও হস্তক্ষেপ হয় এবং enumerateসত্যই সমস্ত মান উত্পন্ন করে a, তবে আপনি অবশেষে একটিটিকে আঘাত করবেন hita এমনf a == b

একটি Boundedএবং Enumউদাহরণ রয়েছে এমন প্রকারের তুচ্ছভাবে তৈরি করা যেতে পারে RecursivelyEnumerableEnumerableপ্রকারের জোড়গুলিও তৈরি করা যায় Enumerable:

instance (Enumerable a, Enumerable b) => Enumerable (a, b) where
    enumerate = crossWith (,) enumerate enumerate

crossWith :: (a -> b -> c) -> [a] -> [b] -> [c]
crossWith f _ [] = []
crossWith f [] _ = []
crossWith f (x0:xs) (y0:ys) =
    f x0 y0 : interleave (map (f x0) ys) 
                         (interleave (map (flip f y0) xs)
                                     (crossWith f xs ys))

interleave :: [a] -> [a] -> [a]
interleave xs [] = xs
interleave [] ys = []
interleave (x:xs) ys = x : interleave ys xs

একই Enumerableধরণের বিভাজনের জন্য যায় :

instance (Enumerable a, Enumerable b) => Enumerable (Either a b) where
    enumerate = enumerateEither enumerate enumerate

enumerateEither :: [a] -> [b] -> [Either a b]
enumerateEither [] ys = map Right ys
enumerateEither xs [] = map Left xs
enumerateEither (x:xs) (y:ys) = Left x : Right y : enumerateEither xs ys

আমরা এটি উভয়ই করতে পারি (,)এবং Eitherসম্ভবত এর অর্থ হ'ল যে কোনও বীজগণিত ডেটা টাইপের জন্য আমরা এটি করতে পারি।


5

প্রতিটি ফাংশনের একটি বিপরীত থাকে না। আপনি যদি আলোচনাটিকে এক-থেকে-এক ফাংশনে সীমাবদ্ধ করেন তবে একটি স্বেচ্ছাসেবী ফাংশন উল্টে দেওয়ার ক্ষমতা যে কোনও ক্রিপ্টোসিস্টেমকে ক্র্যাক করার ক্ষমতা দেয়। আমাদের ধরণের আশা করা দরকার এটি তাত্পর্যপূর্ণ এমনকি বাস্তব নয়!


13
যে কোনও ক্রিপ্টোসিস্টেম (একক সময় প্যাডের মতো কয়েকটি বিজোড় বাদে, যা অন্যান্য কারণে অপরিবর্তনীয়) ব্রুট ফোর্স দ্বারা ক্র্যাক করা যেতে পারে। এটি তাদের কোনও কম দরকারী করে না এবং একটি ব্যবহারিকভাবে ব্যয়বহুল বিপর্যয় ফাংশনও হবে না।

আসলেই কি তাই? যদি আপনি String encrypt(String key, String text)কী ব্যতীত কোনও এনক্রিপশন ফাংশনটি মনে করেন তবে আপনি এখনও কিছু করতে পারবেন না। সম্পাদনা: প্লাস কী ডেলানান বলেছেন।
এমসি

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

"সম্ভাব্য" দ্বারা আমি বোঝাতে চেয়েছি, এমন কিছু যা কোনও যুক্তিসঙ্গত সময়ে করা যায়। আমার অর্থ "গণনাযোগ্য" ছিল না (আমি বেশ নিশ্চিত)।
জেফরি স্কোফিল্ড

@ জেফ্রিস্কোফিল্ড তবে আমার বলতে হবে, আমি "তাত্ত্বিকভাবে সম্ভব" দ্বারা বিভ্রান্ত হয়ে পড়েছি - (আমাদের সংজ্ঞা) সম্ভাব্যতা কেবলমাত্র ব্যবহারিকভাবে করা কতটা কঠিন তা বোঝায় না?

5

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

bijective_function x = x*2+1

main = do
    print $ bijective_function 3
    print $ inverse_function bijective_function (bijective_function 3)

data Expr = X | Const Double |
            Plus Expr Expr | Subtract Expr Expr | Mult Expr Expr | Div Expr Expr |
            Negate Expr | Inverse Expr |
            Exp Expr | Log Expr | Sin Expr | Atanh Expr | Sinh Expr | Acosh Expr | Cosh Expr | Tan Expr | Cos Expr |Asinh Expr|Atan Expr|Acos Expr|Asin Expr|Abs Expr|Signum Expr|Integer
       deriving (Show, Eq)

instance Num Expr where
    (+) = Plus
    (-) = Subtract
    (*) = Mult
    abs = Abs
    signum = Signum
    negate = Negate
    fromInteger a = Const $ fromIntegral a

instance Fractional Expr where
    recip = Inverse
    fromRational a = Const $ realToFrac a
    (/) = Div

instance Floating Expr where
    pi = Const pi
    exp = Exp
    log = Log
    sin = Sin
    atanh = Atanh
    sinh = Sinh
    cosh = Cosh
    acosh = Acosh
    cos = Cos
    tan = Tan
    asin = Asin
    acos = Acos
    atan = Atan
    asinh = Asinh

fromFunction f = f X

toFunction :: Expr -> (Double -> Double)
toFunction X = \x -> x
toFunction (Negate a) = \a -> (negate a)
toFunction (Const a) = const a
toFunction (Plus a b) = \x -> (toFunction a x) + (toFunction b x)
toFunction (Subtract a b) = \x -> (toFunction a x) - (toFunction b x)
toFunction (Mult a b) = \x -> (toFunction a x) * (toFunction b x)
toFunction (Div a b) = \x -> (toFunction a x) / (toFunction b x)


with_function func x = toFunction $ func $ fromFunction x

simplify X = X
simplify (Div (Const a) (Const b)) = Const (a/b)
simplify (Mult (Const a) (Const b)) | a == 0 || b == 0 = 0 | otherwise = Const (a*b)
simplify (Negate (Negate a)) = simplify a
simplify (Subtract a b) = simplify ( Plus (simplify a) (Negate (simplify b)) )
simplify (Div a b) | a == b = Const 1.0 | otherwise = simplify (Div (simplify a) (simplify b))
simplify (Mult a b) = simplify (Mult (simplify a) (simplify b))
simplify (Const a) = Const a
simplify (Plus (Const a) (Const b)) = Const (a+b)
simplify (Plus a (Const b)) = simplify (Plus (Const b) (simplify a))
simplify (Plus (Mult (Const a) X) (Mult (Const b) X)) = (simplify (Mult (Const (a+b)) X))
simplify (Plus (Const a) b) = simplify (Plus (simplify b) (Const a))
simplify (Plus X a) = simplify (Plus (Mult 1 X) (simplify a))
simplify (Plus a X) = simplify (Plus (Mult 1 X) (simplify a))
simplify (Plus a b) = (simplify (Plus (simplify a) (simplify b)))
simplify a = a

inverse X = X
inverse (Const a) = simplify (Const a)
inverse (Mult (Const a) (Const b)) = Const (a * b)
inverse (Mult (Const a) X) = (Div X (Const a))
inverse (Plus X (Const a)) = (Subtract X (Const a))
inverse (Negate x) = Negate (inverse x)
inverse a = inverse (simplify a)

inverse_function x = with_function inverse x

এই উদাহরণটি কেবল গাণিতিক এক্সপ্রেশনগুলির সাথে কাজ করে তবে এটি সম্ভবত তালিকা সহ কাজ করার জন্য সাধারণীকরণ করা যেতে পারে।


4

না, সমস্ত ফাংশন এমনকি বিপরীত হয় না। উদাহরণস্বরূপ, এই ফাংশনটির বিপরীতটি কী হবে?

f x = 1

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