ম্যাকার্থির এলআইএসপি


39

ম্যাকার্থির 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 ।


1
আপনার কাছে একটি ল্যাম্বডা উদাহরণ রয়েছে যা "ইসনুল" ফাংশনটি সংজ্ঞায়িত করছে তবে এটি নীল রিটার্ন নীলের মতো দেখাচ্ছে, যখন মনে হয় এটি টি ফিরে আসবে?
nmjcman101

1
আপনার কাছে ((LAMBDA, (ATOM 1), (EQ, ATOM 1, (QUOTE, NIL))), (QUOTE, NIL)) -> NILকোথায় (QUOTE NIL)শেষে ইনপুট তাই, এই ফিরে যাওয়া উচিত T?
nmjcman101

1
ঠিক আছে, তবে আপনি লিখেছেন-> NIL
nmjcman101

1
আপনার বিবরণে আপনার CONSবক্তব্যটিতে "দ্বিতীয় যুক্তিতে প্রথম যুক্তি সংযোজন করে এবং সদ্য নির্মিত তালিকাটি ফিরিয়ে দেয়" তবে পরীক্ষার কেসগুলি দ্বিতীয় যুক্তিকে প্রথমটিতে সংযুক্ত করে দেখায়। যা সঠিক?
জর্ডান

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

উত্তর:


17

পাইথন 3, 770 বাইট

এটি স্টিডিন / স্টাটআউটে একটি আরপিএল। প্রতিটি লাইন একটি সম্পূর্ণ বিবৃতি বা খালি বলে প্রত্যাশা করে। evalপ্রয়োগটি সংক্ষিপ্ত করতে ব্যবহৃত হয়, তবে অন্যথায় যুক্তির জন্য এটি প্রয়োজনীয় নয়।

import re,sys;S=re.sub
P=lambda l:eval(S("([A-Z0-9][A-Z0-9 ]*)",r"' '.join('\1'.strip().split())",S("NIL","()",S("\)",",)",l))))
d={"QUOTE":'(v,L[1])[1]',"EQ":'[(),"T"][E(L[1],v)==E(L[2],v)]',
"CDR":'E(L[1],v)[1:]',"CONS":'(E(L[1],v),)+E(L[2],v)',"CAR":'E(L[1],v)[0]',
"LAMBDA":'("#",)+L[1:]',"LABEL":'[v.update({L[1]:E(L[2],v)}),L[1]][1]'}
def E(L,v):
 if L*0=="":return v[L]
 elif L[0]in d:return eval(d[L[0]])
 elif L[0]=="COND":return next(E(l[1],v)for l in L[1:]if E(l[0],v)=="T")
 elif L[0]=="ATOM":o=E(L[1],v);return[(),"T"][o*0in["",o]]
 else:l=E(L[0],v);n=v.copy();n.update({a:E(p,v)for a,p in zip(l[1],L[1:])});return E(l[2],n)
R=lambda o:o==()and"NIL"or 0*o==()and"(%s)"%", ".join(R(e)for e in o)or o
g={}
for l in sys.stdin:
 if l.strip():print(R(E(P(l),g)))

1
@ হ্যারি প্রথম দুটি টেস্ট কেস একটি ছোট ত্রুটি ঠিক করার পরে কাজ করে যা আমি চূড়ান্ত ছোঁয়ায় প্রবর্তন করি। খোলামেলা নির্দোষভাবে কাজ করে। তবে SUBSTউদাহরণটি টেস্টকেস হিসাবে এখনও (আমার জ্ঞানের কাছে) ভাঙা। এর মধ্যে CONDএকটি সন্ধানের আগে শেষ পর্যন্ত পৌঁছে যায় T
orlp

1
এটি ঠিক করার জন্য আপনাকে ধন্যবাদ! এটা খুব চিত্তাকর্ষক! এটি এখন সমস্ত টেস্টকেসে আমার পক্ষে কাজ করে, সহ EVAL(এত আনন্দিতভাবে আশ্চর্য হয়েছি যে প্রথমটি চেষ্টা করেই আমি পেয়েছি!) আমি আপনাকে এখন অনুগ্রহ এবং স্বীকৃত উত্তর প্রদান করতে চলেছি!
হ্যারি

2
এছাড়াও আমি R(E(P(l)সেটআপটি পছন্দ করি ;-)
হ্যারি

2
@ হ্যারি আমি আপনাকে বাচ্চা করি না এটি একটি দুর্ঘটনা ছিল! আর = repr, ই = eval, পি = parse, এল = line
orlp

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