ম্যাকার্থির 1959 এলআইএসপি
১৯৫৯ এর গোড়ার দিকে, জন ম্যাকার্থি একটি নয়টি আদিম ক্রিয়াকলাপকে সংজ্ঞায়িত করে একটি যুগোপযোগী কাগজ লিখেছিলেন যা আজও সমস্ত এলআইএসপি-জাতীয় ভাষার ভিত্তি তৈরি করে। কাগজটি এখানে ডিজিটাইজড পাওয়া যায়:
http://www-formal.stanford.edu/jmc/recursive.pdf
অর্থাৎ ফাংশন: আপনার কাজ সম্পূর্ণরূপে একটি পার্সার এবং ম্যাকার্থি এর পাতার মর্মর ঠিক হিসাবে 1960 কাগজে বর্ণিত অনুবাদক বাস্তবায়ন হয় QUOTE
, ATOM
, EQ
, CAR
, CDR
, CONS
, COND
, LAMBDA
, এবং LABEL
সব কার্মিক হওয়া উচিত। উত্তরের যথার্থতা বিবেচনা করার সময় কাগজটি এই চ্যালেঞ্জের পাঠ্যের চেয়ে বেশি প্রাধান্য পাবে, তবে আমি নীচের নয়টি কার্যের সংক্ষিপ্তসার চেষ্টা করেছি। নোট করুন যে ভাষাটি সমস্ত ক্যাপগুলিতে থাকবে এবং কোনও ত্রুটি পরীক্ষা করার প্রয়োজন নেই, সমস্ত ইনপুটটি বৈধ বলে মনে করা উচিত।
প্রকারভেদ
- ম্যাকার্থারির এলআইএসপিতে কেবল দুটি প্রকার রয়েছে: একটি পরমাণু এবং একটি লিঙ্কযুক্ত তালিকা, যা বারে বারে মাথা হিসাবে সংজ্ঞায়িত হয়, যা একটি তালিকা বা একটি পরমাণু হতে পারে, এবং একটি তালিকা যা মাথা সংযুক্ত থাকে (পুচ্ছ) is
NIL
একটি পরমাণু এবং একটি তালিকা উভয়ই থাকার বিশেষ সম্পত্তি রয়েছে। - কাগজ অনুসারে, পরমাণুর নামগুলি কেবল মূল অক্ষর, সংখ্যা এবং মহাকাশ চরিত্র নিয়ে গঠিত হবে, যদিও পরপর স্পেসগুলির স্ট্রিংগুলিকে কেবল একটি স্থান হিসাবে বিবেচনা করা উচিত এবং সমস্ত নেতৃস্থানীয় এবং অনুসরণকারী স্পেস অক্ষর মুছে ফেলা উচিত। উদাহরণ সমতুল্য পরমাণু নাম (স্থান অক্ষর দিয়ে আন্ডারস্কোর প্রতিস্থাপন):
___ATOM__1__ = ATOM_1
। পারমাণবিক নামের সমতুল্য উদাহরণ নয়:A_TOM_1 != ATOM_1
- তালিকা বন্ধনী দ্বারা চিহ্নিত করা হয়, এবং
NIL
প্রতিটি সূচকের শেষে একটি অন্তর্নিহিত হয়। একটি তালিকার উপাদানগুলি কমা দ্বারা পৃথক করা হয় এবং বেশিরভাগ আধুনিক লিস্পের মতো সাদা স্থান নয় । সুতরাং তালিকা(ATOM 1, (ATOM 2))
হতে হবে{[ATOM 1] -> {[ATOM 2] -> NIL} -> NIL}
।
QUOTE
:
- একটি যুক্তি নেয় যা হয় পরমাণু (একক উপাদান) বা একটি লিঙ্কযুক্ত তালিকা হতে পারে। যুক্তিটি হুবহু ফেরায়।
- পরীক্ষার কেস:
(QUOTE, ATOM 1) -> ATOM 1
(QUOTE, (ATOM 1, ATOM 2)) -> (ATOM 1, ATOM 2)
ATOM
:
- একটি যুক্তি নেয় যা হয় পরমাণু (একক উপাদান) বা একটি লিঙ্কযুক্ত তালিকা হতে পারে। রিটার্নস
T
(সত্য) হলে যুক্তি পরমাণুর, বাNIL
(মিথ্যা) যদি যুক্তি পরমাণুর নয়। - পরীক্ষার কেস:
(ATOM, (QUOTE, ATOM 1)) -> T
(ATOM, (QUOTE, (ATOM 1, ATOM 2))) -> NIL
EQ
:
- দুটি আর্গুমেন্ট নেয় যা অবশ্যই পরমাণু হতে হবে (তর্কগুলির মধ্যে দুটি যদি পরমাণু না হয় তবে আচরণটি সংজ্ঞায়িত হয়)। রিটার্নস
T
(সত্য) যদি দুটি পরমাণু সমতুল্য, বা হয়NIL
যদি তারা না (মিথ্যা)। - পরীক্ষার কেস:
(EQ, (QUOTE, ATOM 1), (QUOTE, ATOM 1)) -> T
(EQ, (QUOTE, ATOM 1), (QUOTE, ATOM 2)) -> NIL
CAR
:
- একটি যুক্তি নেয় যা অবশ্যই একটি তালিকা হতে হবে (তালিকাটি না হলে আচরণটি অপরিজ্ঞাত)। সেই তালিকার প্রথম অণু (মাথা) ফেরত দেয়।
- পরীক্ষার কেস:
(CAR, (QUOTE, (ATOM 1, ATOM 2))) -> ATOM 1
CDR
:
- একটি যুক্তি নেয় যা অবশ্যই একটি তালিকা হতে হবে (তালিকাটি না হলে আচরণটি অপরিজ্ঞাত)। প্রতিটি পরমাণু কিন্তু তালিকার প্রথম পরমাণু, যেমন পুচ্ছ ফিরে দেয়। নোট করুন যে প্রতিটি তালিকা একটি অন্তর্নিহিত মধ্যে শেষ হয়
NIL
, সুতরাংCDR
একটি তালিকায় চলমান যে কেবল একটি উপাদান রয়েছে বলে মনে হচ্ছে তা ফিরে আসবেNIL
। - পরীক্ষার কেস:
(CDR, (QUOTE, (ATOM 1, ATOM 2))) -> (ATOM 2)
(CDR, (QUOTE, (ATOM 1))) -> NIL
CONS
:
- দুটি যুক্তি গ্রহণ করে। প্রথমটি একটি পরমাণু বা একটি তালিকা হতে পারে তবে দ্বিতীয়টি অবশ্যই একটি তালিকা বা
NIL
। দ্বিতীয় যুক্তিতে প্রথম যুক্তি প্রস্তুত করে এবং সদ্য নির্মিত তালিকাটি ফেরত দেয়। - পরীক্ষার কেস:
(CONS, (QUOTE, ATOM 1), (QUOTE, NIL)) -> (ATOM 1)
(CONS, (QUOTE, ATOM 1), (CONS, (QUOTE, ATOM 2), (QUOTE, NIL))) -> (ATOM 1, ATOM 2)
COND
:
- এটি এলআইএসপি'র "যদি-অন্য" ধরণের বিবৃতি statement একটি চলক-দৈর্ঘ্যের পরিমাণে আর্গুমেন্ট গ্রহণ করে, যার প্রত্যেকটি অবশ্যই দৈর্ঘ্যের একটি তালিকা হতে হবে 2. প্রতিটি তর্ক তালিকার জন্য ক্রমানুসারে প্রথম পদটি মূল্যায়ন করুন এবং যদি এটি সত্য (টি) হয় তবে যুক্ত দ্বিতীয় পদটি ফিরে আসুন এবং ফাংশনটি প্রস্থান করুন । যদি প্রথম শব্দটি সত্য না হয়, পরবর্তী যুক্তিতে এগিয়ে যান এবং তার অবস্থার পরীক্ষা করুন এবং প্রথম সত্য শর্তটি না পৌঁছানো পর্যন্ত। কমপক্ষে একটি যুক্তি শর্তটিকে সত্য বলে ধরে নেওয়া যেতে পারে - যদি তারা সমস্ত মিথ্যা হয় তবে এটি অনির্ধারিত আচরণ। এই ফাংশনটির আচরণের একটি ভাল উদাহরণের জন্য পৃষ্ঠা 4 দেখুন।
- পরীক্ষার কেস:
(COND, ((ATOM, (QUOTE, ATOM 1)), (QUOTE, 1)), ((ATOM, (QUOTE, (ATOM 1, ATOM 2))), (QUOTE, 2))) -> 1
(COND, ((ATOM, (QUOTE, (ATOM 1, ATOM 2))), (QUOTE, 2)), ((ATOM, (QUOTE, ATOM 1)), (QUOTE, 1))) -> 1
LAMBDA
:
- একটি বেনামী ফাংশন সংজ্ঞায়িত করে। দুটি আর্গুমেন্ট নেয়, প্রথমটি হল অণুগুলির তালিকা যা ফাংশনে আর্গুমেন্টগুলি উপস্থাপন করে এবং দ্বিতীয়টি কোনও এস-এক্সপ্রেশন (ফাংশন বডি), যা সাধারণত আর্গুমেন্টগুলি ব্যবহার করে।
- পরীক্ষার কেস:
- একটি বেনাম "isNull" ফাংশন সংজ্ঞা এবং ব্যবহার:
((LAMBDA, (ATOM 1), (EQ, ATOM 1, (QUOTE, NIL))), (QUOTE, NIL)) -> T
((LAMBDA, (ATOM 1), (EQ, ATOM 1, (QUOTE, NIL))), (QUOTE, ATOM 1)) -> NIL
LABEL
:
- একটি বেনামী একটি নাম দেয়
LAMBDA
ফাংশন, যা দেয় ফাংশনের শরীরে যাও recursively বলা হবেLAMBDA
। দুটি আর্গুমেন্ট নেয়, প্রথমটি হ'ল একটি লেবেল এবং দ্বিতীয়টিLAMBDA
ফাংশন যার সাথে লেবেলটি আবদ্ধ হওয়া উচিত। সরবরাহ করা নামটি ফেরত দেয়। সমস্তLABEL
নামের ক্ষেত্রটি বিশ্বব্যাপী, এবং একটিটির নতুন সংজ্ঞা দেওয়াLABEL
অনির্ধারিত আচরণ। - মজাদার ঘটনাটি,
LABEL
পুনরাবৃত্ত ফাংশনগুলি তৈরি করা আসলে প্রয়োজনীয় নয় কারণ এখন আমরা জানিLAMBDA
যে এই কাজটি সম্পাদন করতে একটি 'ওয়াই-কম্বিনেটর' ব্যবহার করা যেতে পারে , তবে ম্যাকার্থি মূল কাগজটি লেখার সময় এই পদ্ধতি সম্পর্কে অবগত ছিলেন না। এটি যাইহোক প্রোগ্রাম লিখতে অনেক সহজ করে তোলে। - পরীক্ষার কেস:
(LABEL, SUBST, (LAMBDA, (X, Y, Z), (COND, ((ATOM, Z), (COND, ((EQ, Y, Z), X), ((QUOTE, T), Z))), ((QUOTE, T), (CONS, (SUBST, X, Y, (CAR, Z)), (SUBST, X, Y, (CDR, Z))))))) -> SUBST
- (উপরের দৌড়ানোর পরে)
(SUBST, (QUOTE, A), (QUOTE, B), (QUOTE, (A, B, C))) -> (A, A, C)
SUBST
উপরের ক্রিয়াকলাপটি কল্পনা করতে সহায়তা করার জন্য , এটি এই পাইথনের মতো সিউডোকোড হিসাবে উপস্থাপন করা যেতে পারে:
def substitute(x, y, z): # substitute all instances of y (an atom) with x (any sexp) in z
if isAtom(z):
if y == z:
return x
elif True:
return z
elif True:
return substitute(x,y,z[0]) + substitute(x,y,z[1:])
শেষ পরীক্ষার মামলা:
যদি আমি এটি সঠিকভাবে প্রতিলিপি করি তবে আপনার দোভাষী EVAL
এই কোডটি দিয়ে ব্যাখ্যা করতে সক্ষম হবেন :
(LABEL, CAAR, (LAMBDA, (X), (CAR, (CAR, X))))
(LABEL, CDDR, (LAMBDA, (X), (CDR, (CDR, X))))
(LABEL, CADR, (LAMBDA, (X), (CAR, (CDR, X))))
(LABEL, CDAR, (LAMBDA, (X), (CDR, (CAR, X))))
(LABEL, CADAR, (LAMBDA, (X), (CAR, (CDR, (CAR, X)))))
(LABEL, CADDR, (LAMBDA, (X), (CAR, (CDR, (CDR, X)))))
(LABEL, CADDAR, (LAMBDA, (X), (CAR, (CDR, (CDR, (CAR, X))))))
(LABEL, ASSOC, (LAMBDA, (X, Y), (COND, ((EQ, (CAAR, Y), X), (CADAR, Y)), ((QUOTE, T), (ASSOC, X, (CDR, Y))))))
(LABEL, AND, (LAMBDA, (X, Y), (COND, (X, (COND, (Y, (QUOTE, T)), ((QUOTE, T), (QUOTE, NIL)))), ((QUOTE, T), (QUOTE, NIL)))))
(LABEL, NOT, (LAMBDA, (X), (COND, (X, (QUOTE, NIL)), ((QUOTE, T), (QUOTE, T)))))
(LABEL, NULL, (LAMBDA, (X), (AND, (ATOM, X), (EQ, X, (QUOTE, NIL)))))
(LABEL, APPEND, (LAMBDA, (X, Y), (COND, ((NULL, X), Y), ((QUOTE, T), (CONS, (CAR, X), (APPEND, (CDR, X), Y))))))
(LABEL, LIST, (LAMBDA, (X, Y), (CONS, X, (CONS, Y, (QUOTE, NIL)))))
(LABEL, PAIR, (LAMBDA, (X, Y), (COND, ((AND, (NULL, X), (NULL, Y)), (QUOTE, NIL)), ((AND, (NOT, (ATOM, X)), (NOT, (ATOM, Y))), (CONS, (LIST, (CAR, X), (CAR, Y)), (PAIR, (CDR, X), (CDR, Y)))))))
(LABEL, EVAL, (LAMBDA, (E, A), (COND, ((ATOM, E), (ASSOC, E, A)), ((ATOM, (CAR, E)), (COND, ((EQ, (CAR, E), (QUOTE, QUOTE)), (CADR, E)), ((EQ, (CAR, E), (QUOTE, ATOM)), (ATOM, (EVAL, ((CADR, E), A)))), ((EQ, (CAR, E), (QUOTE, EQ)), (EQ, (EVAL, (CADR, E, A)), (EVAL, (CADDR, E, A)))), ((EQ, (CAR, E), (QUOTE, COND)), (EVCON, (CDR, E), A)), ((EQ, (CAR, E), (QUOTE, CAR)), (CAR, (EVAL, (CADR, E), A))), ((EQ, (CAR, E), (QUOTE, CDR)), (CDR, (EVAL, (CADR, E), A))), ((EQ, (CAR, E), (QUOTE, CONS)), (CONS, (EVAL, (CADR, E), A), (EVAL, (CADDR, E), A))), ((QUOTE, T), (EVAL, (CONS, (ASSOC, (CAR, E), A), (EVLIS, (CDR, E), A)), A)))), ((EQ, (CAAR, E), (QUOTE, LABEL)), (EVAL, (CONS, (CADDAR, E), (CDR, E)), (CONS, (CONS, (CADAR, E), (CONS, (CAR, E), (CONS, A, (QUOTE, NIL))))))), ((EQ, (CAAR, E), (QUOTE, LAMBDA)), (EVAL, (CADDAR, E), (APPEND, (PAIR, (CADAR, E), (EVLIS, (CDR, E), A)), A))))))
(LABEL, EVCON, (LAMBDA, (C, A), (COND, ((EVAL, (CAAR, C), A), (EVAL, (CADAR, C), A)), ((QUOTE, T), (EVCON, (CDR, C), A)))))
(LABEL, EVLIS, (LAMBDA, (M, A), (COND, ((NULL, M), (QUOTE, NIL)), ((QUOTE, T), (CONS, (EVAL, (CAR, M), A), (EVLIS, (CDR, M), A))))))
সেই বেহেমথ চালানোর পরে, এই লাইনটি ফিরে আসবে (A, B, C)
:
(EVAL, (QUOTE, (CONS, X, (QUOTE, (B, C)))), (QUOTE, ((X, A), (Y, B))))
যাইহোক, জন ম্যাকার্থি নিজেই 16 পৃষ্ঠায় উদ্ধৃত করার জন্য, মনে হয় তিনি নিজের কম্পিউটারে অক্ষরগুলি সরিয়ে চলেছেন:
কম্পিউটারে আরও অক্ষর পাওয়া গেলে, এটি যথেষ্ট উন্নত হতে পারে ...
অতএব, এই চ্যালেঞ্জটি কোড-গল্ফকে ট্যাগ করা হয়েছে এবং চরিত্রগুলির মধ্যে সংক্ষিপ্ত উত্তরটি বিজয়ী হবে। স্ট্যান্ডার্ড লুফোলস প্রযোজ্য। শুভকামনা!
স্ট্রিং ইভালসের উপর নোট : আমি বুঝতে পেরেছি যে কেউ কেউ মনে করেন যে একটি লিপ্প ব্যবহার করে এবং হোস্ট ভাষার সাথে মানানসই সিনট্যাক্সটি সংশোধন করে এবং তারপরে একটি স্ট্রিং ব্যবহার করে এই চ্যালেঞ্জটি জেতা সম্ভব think(eval)
। আমি বিশেষভাবে নিশ্চিত নই যে এই পদ্ধতিটি প্রয়োজনীয়ভাবে বিশেষত শনাক্তকারী নামকরণের নিয়মগুলির সাথে জিতবে, এবং এমনকি যদি আমি এটি ভাবিও eval
না যে সমস্ত ভাষায় স্ট্রিংয়ের নিষিদ্ধ করা একটি বিষয়গত এবং পিচ্ছিল opeাল হবে। তবে এই চ্যালেঞ্জটি সঠিকভাবে করার জন্য আমি মানুষকে শাস্তি দিতে চাই না, সুতরাং আমি এই চ্যালেঞ্জের জন্য দু'জন বিজয়ীকে অনুমতি দিতে পারি, একটি লিপ-জাতীয় ভাষায় এবং একজন যদি লিস্পি ভাষায় নয়, যদি এটি সমস্যা হয়ে যায় if ।
((LAMBDA, (ATOM 1), (EQ, ATOM 1, (QUOTE, NIL))), (QUOTE, NIL)) -> NIL
কোথায় (QUOTE NIL)
শেষে ইনপুট তাই, এই ফিরে যাওয়া উচিত T
?
-> NIL
CONS
বক্তব্যটিতে "দ্বিতীয় যুক্তিতে প্রথম যুক্তি সংযোজন করে এবং সদ্য নির্মিত তালিকাটি ফিরিয়ে দেয়" তবে পরীক্ষার কেসগুলি দ্বিতীয় যুক্তিকে প্রথমটিতে সংযুক্ত করে দেখায়। যা সঠিক?