ת.ז. עמוד 1 מס' מחברת סמסטר ב' תשס"ט ,מועד א' יום שלישי 7 ,ביולי 2009 בחינת סיום -מבוא מורחב למדעי המחשב 0368.1105 מרצים :טובה מילוא ודניאל דויטש מתרגלים :אייל כהן ואלכסנדר אפראצין הוראות כלליות .1משך הבחינה שלוש שעות. .2בבחינה 4שאלות .יש לענות על כל השאלות. .3חומר עזר מותר בשימוש :כל חומר כתוב או מודפס שהבאת אתך. .4יש לענות על כל השאלות .משקלן אינו משקף בהכרח את הקושי והזמן הדרוש לפתרונן. .5ניתן להשתמש בכל פונקציה שהוזכרה בשיעור או מופיעה בספר .כמו כן מותר להשתמש בפרוצדורות מסעיפים קודמים גם אם לא ענית על סעיפים אלו. .6כתוב את כל תשובותיך בטופס המבחן – המחברת לא תבדק! .7בשאלות בהן יש להשלים קוד בתבנית ,אין לכתוב קוד אשר אינו תואם את התבנית. אורך הקווים בתבנית אינו בהכרח רומז על ביטוי קצר או ארוך. .8יש לקרוא בעיון את השאלות. .9עזרו לבודק המבחן לבדוק את עבודתכם — כתבו בצורה נקיה ומסודרת .10הבחינה מכילה 19עמודים (כולל עמוד זה). בהצלחה!! טבלה זו לשימוש הבודקים בלבד!! 1 2 3 4 סה"כ ת.ז. מס' מחברת עמוד 2 שאלה 35( 1נק') הערה :כל ההתייחסויות בשאלה זו לסיבוכיות מתייחסות לסיבוכיות זמן כזכור ,רשימה מקושרת רגילה היא מבנה נתונים הכולל איברים ,כאשר כל איבר כולל ערך ומצביע אל האיבר הבא ברשימה .מבנה נתונים זה מאפשר להגיע בסיבוכיות זמן ) O(1אל האיבר הראשון ברשימה ,מאפשר לקבל מכל איבר את הערך השמור בו, וגם מאפשר ,בהינתן מצביע לאיבר כלשהו ברשימה ,להגיע אל האיבר הבא ברשימה בסיבוכיות ).O(1 בשאלה זו נגדיר מבנה נתונים חדש ,בשם רשימה מקושרת כפולה) ,(dllistשתאפשר לנו בנוסף ליכולות של רשימה מקושרת רגילה ,גם להגיע אל האיבר האחרון ב- ) ,O(1וגם ,בהינתן מצביע לאיבר כלשהו ,להגיע אל האיבר הקודם לו ב.O(1) - כלומר ,מבנה הנתונים החדש תומך בפעולות הבאות (ממומשות בהמשך) ,כולן בסיבוכיות זמן ):O(1 )(make-dllist מייצר רשימה מקושרת כפולה ריקה )(dllist-head dll מקבל רשימה מקושרת כפולה ,ומחזיר מצביע אל האיבר הראשון בה )(dllist-tail dll מקבל רשימה מקושרת כפולה ומחזיר מצביע אל האיבר האחרון בה ((make-elem val next prev מקבל ערך ,valמצביע לאיבר nextומצביע לאיבר ,prevומייצר איבר חדש ,שהערך שלו הוא ,valהאיבר הבא לו הוא , nextוהאיבר הקודם לו הוא .prev ((dll-elem-value elem מקבל מצביע לאיבר ברשימה ומחזיר את הערך השמור בו )(dllist-elem-next elem מקבל מצביע לאיבר ברשימה ומחזיר מצביע לאיבר הבא אחריו )(dllist-elem-prev elem מקבל מצביע לאיבר ברשימה ,ומחזיר מצביע לאיבר הקודם לו 3 עמוד מס' מחברת .ז.ת (dllist-empty? dll) אחרת#f , אם היא ריקה#t מקבל רשימה מקושרת כפולה ומחזיר (dllist-insert-at-start! dll val) .dll בתחילת הרשימה המקושרת הכפולהval מכניס איבר שערכו :נתון המימוש הבא לרשימה מקושרת כפולה ;Constructors (define (make-dllist) (cons null null)) (define (make-elem val next prev) (list val next prev)) ;Selectors: (define (dllist-head dll) (car dll)) (define (dllist-tail dll) (cdr dll)) (define (dllist-elem-value elem) (car elem)) (define (dllist-elem-next elem) (cadr elem)) (define (dllist-elem-prev elem) (caddr elem)) ;Predicate: (define (dllist-empty? dll) (null? (car dll))) ;Mutator: (define (dllist-insert-at-start! dll val) (let ((new_elem (make-elem val (dllist-head dll) null))) (cond ((dllist-empty? dll) (begin (set-car! dll new_elem) (set-cdr! dll new_elem))) (else (begin (set-car! (cddr (dllist-head dll)) new_elem) (set-car! dll new_elem) ))))) ת.ז. עמוד 4 מס' מחברת א )i( .ציירו במסגרת את המבנה (זוגות ומצביעים) אליו מצביע pלאחר סיום שערוך הביטויים הבאים: ))(define p (make-dllist )(dllist-insert-at-start! p 1 )(dllist-insert-at-start! p 2 )(dllist-insert-at-start! p 3 ( )iiמה יציג המשערך כתוצאה משערוך הביטויים הבאים, (לאחר שכבר שערך את הביטויים שבסעיף ( )iלעיל)? )))(dllist-elem-value (dllist-elem-next (dllist-head p )))(dllist-elem-value (dllist-elem-prev (dllist-tail p _________________________________________________ _________________________________________________ הערה – בסעיפים ב' – ד' מותר לכם להשתמש בפונק' הממשק שהוגדרו לעיל. ת.ז. מס' מחברת עמוד 5 ב .כתבו בעמ' הבא פונקציה ) (list->dllist lstשמקבלת מצביע לרשימה מקושרת רגילה ,שכל איבריה מספריים ,ומחזירה מצביע לרשימה מקושרת כפולה עם אותם ערכים ,באותו סדר. )(define (list->dllist lst __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ )__________________________________________________ ג )1( .כתבו פונקציה אשר מקבלת מצביע DLלרשימה מקושרת כפולה ,שניתן להניח שכל ערכיה הם סימבולים ,ומסירה )תוך שימוש ב)mutation - כפילויות ,כדלהלן :בכל פעם שסימבול מופיע יותר מפעם אחת ברשימה, הפונקציה מסירה את כל המופעים שלו פרט לאחרון שבהם. )(define (dllist-delete-dup! DL ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ת.ז. עמוד 6 מס' מחברת ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ ______________________________________________________ )______________________________________________________ ( )2מהי סיבוכיות זמן הריצה של הפונקציה ! ,dllist-delete-dupכאשר nמסמן את אורך הרשימה? _________________________________________________ ד .כתבו פונקציה אשר מקבלת סימבול ,symומצביע DLלרשימה מקושרת כפולה ,שניתן להניח שכל ערכיה הם סימבולים או מצביעים לרשימות מקושרות כפולות (שערכיהן הם גם כן ,סימבולים או מצביעים לרשימות מקושרות כפולות וכן הלאה) .הפונקציה מחזירה רשימה מקושרת כפולה חדשה ,שנראית כמו DLפרט לכך שכל איבר מ DL -שערכו הוא symהוסר ממנה .הרשימה המוחזרת היא חדשה ,במובן זה ששום שינוי ברשימה המקורית לא משנה את הרשימה החדשה ולהיפך. )(define (dllist-delete-sym DL sym ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________ 7 עמוד מס' מחברת .ז.ת ________________________________________________________ ________________________________________________________ ________________________________________________________ ________________________________________________________) )' נק20( 2 שאלה .ציירו (בעמוד הבא) את מהלך השערוך של הביטויים הבאים במודל הסביבות ?מה יוצג על גבי המסך כתוצאה משערוך הביטויים ___________________________________________________________ ___________________________________________________________ ___________________________________________________________ ___________________________________________________________ ___________________________________________________________ (define (f res1 res2 counter) (define (g) (set! res2 (list res2 res2)) (set-cdr! res1 res2) ) ;end of g (g) (display (car res1)) (newline) (display res2) (newline) (if (= counter 0) g (f res1 res2 (- counter 1))) ) ;end of f (define p '(6)) (define x 6) (define tmp (f p x 1)) ת.ז. מס' מחברת עמוד 8 הערות: .1הקפידו למספר את הסביבות שנוצרות לפי סדר פתיחתן. .2הקריאות ל newline ,display -לא יוצרות סביבה חדשה .3יש לצייר גם את מבני הרשימות והזוגות הנוצרים במהלך הריצה GE ><... ת.ז. מס' מחברת עמוד 9 שאלה 25( 3נק') שאלה זו עוסקת בזרמים (.)streams א .השלימו את הקוד של פונקצית ? in-sortedהמקבלת מספר וזרם ()stream אינסופי של מספרים ממוינים בסדר עולה .הפונקציה מחזירה #tאם המספר שהיא מקבלת נמצא בתוך ה stream-ו #f -אחרת. לדוגמא (in-sorted 13 fibs) :צריך להחזיר #tכי 13הינו מספר פיבונצ'י ) (in-sorted 14 stream-of-fibsצריך להחזיר #fכי 14איננו מספר פיבונצ'י. )(define (in-sorted? x s _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ ) ב .נגדיר קונבולוציה בין רשימת המספרים ) (a1 a2 .. anוזרם ( )streamאינסופי של מספרים ]… [b1 b2 b3להיות זרם אינסופי של מספרים ] … [c1 c2 c3כך ש. ci= a1*bi+a2*bi+1 ... an*bi+n - לדוגמא (stream-conv ‘(1 2) fibs) :צריך להחזיר ]……[2 3 5 8 13 21 34 55 89 השלימו את הקוד של פונקצית ,stream-convהמחשבת קונבולוציה כפי שהוגדרה. ת.ז. עמוד 10 מס' מחברת )(define (stream-conv lst str ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ ___________________________________ )___________________________________ שימו לב :סעיף ג' בעמוד הבא 11 עמוד מס' מחברת .ז.ת ? אחרי שיערוך של ההגדרות שלהלןx2 - וx1 מה יהיו הערכים של.ג X1=________________ (define x1 0) (define x2 0) (define str1 (cons-stream 1 (begin (set! x1 (+ x1 1)) str1) )) (define (integers n) (cons-stream n (begin (set! x2 (+ x2 1)) (integers (+ n 1)) ))) (define str2 (integers 1)) (define c1 (stream-conv '(1 1) str1)) (define c2 (stream-conv '(1 1) str2)) X2=__________ ת.ז. עמוד 12 מס' מחברת שאלה 20( 4נק') בשאלה זו נרחיב את המשערך המטא-מעגלי mc-evalכך שיתמוך בביטוי special form מהצורה ).(loop init cond update body loopהיא פקודה חדשה וכל אחד מארבעת הביטויים שאחריה עשוי להיות כל ביטוי. המשמעות של ביטוי זה: ( )1שערך את ביטוי ה init -פעם אחת ( )2שערך את ביטוי ה .cond -אם ערכו שונה מ ,#t -סיים את השערוך ( )3אם ערכו של ביטוי ה cond -הוא ,#tשערך את bodyואז שערך את ,update וחזור לשלב 2להמשך שערוך הערך שמוחזר בסיום השערוך הוא הערך של השערוך האחרון של .bodyאם body לא שוערך כלל ,יוחזר הסימבול 'OK לדוגמא: )(loop (define x 0 )(< x 3 ))(set! x (+ x 1 ))(display x ידפיס את המספרים .0 1 2זאת מכיוון שקודם ישוערך ) (define x 0פעם אחת ,ואז ישוערך התנאי ) (< x 3שיחזיר .#tלכן ישוערך ) ,(display xשידפיס ,0ואז ( ) (set! x (+ x 1שיעדכן את ערכו של xלהיות .1אז שוב ישוערכו התנאי ,ההדפסה ופעולת ההשמה (בסדר הזה) ,וחוזר חלילה ,עד אשר ערכו של xיהיה ,3התנאי לא יתקיים ושערוך הביטוי יסתיים. א .השלם את ההגדרות הבאות: ;predicate )__________________________________________ )(define (loop? exp ;selectors )_______________________________________ )(define (loop-init exp ת.ז. עמוד 13 מס' מחברת )______________________________________ )(define (loop-cond exp )____________________________________ )(define (loop-update exp )_____________________________________ )(define (loop-body exp ב .השלימו את מימוש הפונקציה eval-loopהמשערך ביטוי מסוג loop )(define (eval-loop exp env ))_________________ (let ((tmp )(define (help-eval-loop __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ )__________________________________________________ ____________________________________________________ ____________________________________________________ ____________________________________________________ ____________________________________________________ ))__________________________________________________ ג .כעת נותר להוסיף שורת קוד נוספת לפונקציה mc-evalכדי לתמוך בפקודת .loop מהי השורה והיכן תוסיפו אותה? שורת הקוד הנוספת: ________________________________________________________ היכן ,בתוך הפונקציה ,תוסיפו את שורה זו? ________________________________________________________ ________________________________________________________ ת.ז. מס' מחברת עמוד 14 15 עמוד מס' מחברת Running loop: (define input-prompt ";;; M-Eval input:") (define output-prompt ";;; M-Eval value:") (define (driver-loop) (prompt-for-input input-prompt) (let ((input (read))) (let ((output (mc-eval input the-global-environment))) (cond ((eq? output exit-object) 'done) (else (announce-output output-prompt) (user-print output) (driver-loop)))))) (define (prompt-for-input string) (newline) (newline) (display string) (newline)) (define (announce-output string) (newline) (display string) (newline)) (define exit-object (cons nil nil)) (define (exit-driver) exit-object) (define (user-print object) (if (compound-procedure? object) (display (list 'compound-procedure (procedure-parameters object) (procedure-body object) '<procedure-env>)) (display object))) Eval: (define (mc-eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((quoted? exp) (text-of-quotation exp)) ((assignment? exp) (eval-assignment exp env)) ((definition? exp) (eval-definition exp env)) ((if? exp) (eval-if exp env)) ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) ((begin? exp) (eval-sequence (begin-actions exp) env)) ((cond? exp) (mc-eval (cond->if exp) env)) ((application? exp) (mc-apply (mc-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- MC-EVAL" exp)))) (define (eval-sequence exps env) (cond ((last-exp? exps) (mc-eval (first-exp exps) env)) (else (mc-eval (first-exp exps) env) (eval-sequence (rest-exps exps) env)))) (define (last-exp? seq) (null? (cdr seq))) (define (first-exp seq) (car seq)) .ז.ת 16 עמוד מס' מחברת (define (rest-exps seq) (cdr seq)) Apply: (define (mc-apply procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments (procedure-environment procedure)))) (else (error "Unknown procedure type -- MC-APPLY" procedure)))) (define (primitive-procedure? proc) (tagged-list? proc 'primitive)) (define (apply-primitive-procedure proc args) (apply-in-underlying-scheme (primitive-implementation proc) args)) (define apply-in-underlying-scheme apply) (define (compound-procedure? p) (tagged-list? p 'procedure)) (define (procedure-parameters p) (cadr p)) (define (procedure-body p) (caddr p)) (define (procedure-environment p) (cadddr p)) The Global Enviroment: (define the-global-environment (setup-environment)) (define (setup-environment) (let ((initial-env (extend-environment (primitive-procedure-names) (primitive-procedure-objects) the-empty-environment))) (define-variable! 'true true initial-env) (define-variable! 'false false initial-env) initial-env)) (define primitive-procedures (list (list 'car car) (list 'cdr cdr) (list 'cons cons) (list 'null? null?) (list '+ +) (list '- -) (list '* *) (list '/ /) (list '= =) (list 'print user-print) (list 'exit exit-driver) ;; more primitives )) (define (primitive-procedure-names) (map car primitive-procedures)) (define (primitive-procedure-objects) (map (lambda (proc) (list 'primitive (cadr proc))) primitive-procedures)) .ז.ת 17 עמוד מס' מחברת .ז.ת (define (primitive-implementation proc) (cadr proc)) (define the-empty-environment '()) (define (extend-environment vars vals base-env) (if (= (length vars) (length vals)) (cons (make-frame vars vals) base-env) (if (< (length vars) (length vals)) (error "Too many arguments supplied" vars vals) (error "Too few arguments supplied" vars vals)))) (define (make-frame variables values) (cons variables values)) (define (frame-variables frame) (car frame)) (define (frame-values frame) (cdr frame)) Self evaluating: ((self-evaluating? exp) exp) (define (self-evaluating? exp) (cond ((number? exp) true) ((string? exp) true) (else false))) Combination expression: (operator exp) env) ((application? exp) (mc-apply (mc-eval (list-ofvalues (operands exp) env))) (define (application? exp) (pair? exp)) (define (operator exp) (car exp)) (define (operands exp) (cdr exp)) (define (list-of-values exps env) (if (no-operands? exps) '() (cons (mc-eval (first-operand exps) env) (list-of-values (rest-operands exps) env)))) (define (no-operands? ops) (null? ops)) (define (first-operand ops) (car ops)) (define (rest-operands ops) (cdr ops)) lambda expression: parameters exp) ((lambda? exp) (make-procedure (lambda- (lambda-body exp) env)) (define (lambda? exp)(tagged-list? exp 'lambda)) (define (lambda-parameters exp) (cadr exp)) (define (lambda-body exp) (cddr exp)) (define (make-procedure parameters body env) (list 'procedure parameters body env)) quote expression: ((quoted? exp) (text-of-quotation exp)) (define (quoted? exp) (tagged-list? exp 'quote)) (define (text-of-quotation exp) (cadr exp)) if expression: ((if? exp) (eval-if exp env)) (define (if? exp) (tagged-list? exp 'if)) (define (eval-if exp env) 18 עמוד מס' מחברת (if (true? (mc-eval (if-predicate exp) env)) (mc-eval (if-consequent exp) env) (mc-eval (if-alternative exp) env))) (define (if-predicate exp) (cadr exp)) (define (if-consequent exp) (caddr exp)) (define (if-alternative exp) (if (not (null? (cdddr exp))) (cadddr exp) 'false)) begin expression: env)) ((begin? exp)(eval-sequence (begin-actions exp) (define (begin? exp) (tagged-list? exp 'begin)) (define (begin-actions exp) (cdr exp)) (define (eval-sequence exps env) (cond ((last-exp? exps) (mc-eval (first-exp exps) env)) (else (mc-eval (first-exp exps) env) (eval-sequence (rest-exps exps) env)))) (define (last-exp? seq) (null? (cdr seq))) (define (first-exp seq) (car seq)) (define (rest-exps seq) (cdr seq)) cond expression: ((cond? exp) (mc-eval (cond->if exp) env)) (define (cond? exp) (tagged-list? exp 'cond)) (define (cond->if exp) (expand-clauses (cond-clauses exp))) (define (cond-clauses exp) (cdr exp)) (define (expand-clauses clauses) (if (null? clauses) 'false ; no else clause (let ((first (car clauses)) (rest (cdr clauses))) (if (cond-else-clause? first) (if (null? rest) (sequence->exp (cond-actions first)) (error "ELSE clause isn't last -- COND->IF" clauses)) (make-if (cond-predicate first) (sequence->exp (cond-actions first)) (expand-clauses rest)))))) (define (cond-else-clause? clause) (eq? (cond-predicate clause) 'else)) (define (cond-predicate clause) (car clause)) (define (cond-actions clause) (cdr clause)) (define (make-if predicate consequent alternative) (list 'if predicate consequent alternative)) (define (sequence->exp seq) (cond ((null? seq) seq) ((last-exp? seq) (first-exp seq)) (else (make-begin seq)))) .ז.ת 19 עמוד מס' מחברת (define (last-exp? seq) (null? (cdr seq))) (define (first-exp seq) (car seq)) (define (make-begin seq) (cons 'begin seq)) Variables: ((variable? exp) (lookup-variable-value exp env)) (define (variable? exp) (symbol? exp)) (define (lookup-variable-value var env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (car vals)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env)) (define (enclosing-environment env) (cdr env)) (define (first-frame env) (car env)) set! expression: ((assignment? exp) (eval-assignment exp env)) (define (assignment? exp) (tagged-list? exp 'set!)) (define (eval-assignment exp env) (set-variable-value! (assignment-variable exp) (mc-eval (assignment-value exp) env) env) 'ok) (define (assignment-variable exp) (cadr exp)) (define (assignment-value exp) (caddr exp)) (define (set-variable-value! var val env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (set-car! vals val)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable -- SET!" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env)) (define (enclosing-environment env) (cdr env)) (define (first-frame env) (car env)) define expression: ((definition? exp) (eval-definition exp env)) (define (definition? exp) (tagged-list? exp 'define)) (define (eval-definition exp env) .ז.ת 20 עמוד מס' מחברת (define-variable! (definition-variable exp) (mc-eval (definition-value exp) env) env) 'ok) (define (definition-variable exp) (if (symbol? (cadr exp)) (cadr exp) (caadr exp))) (define (definition-value exp) (if (symbol? (cadr exp)) (caddr exp) (make-lambda (cdadr exp) (cddr exp)))) (define (make-lambda parameters body) (cons 'lambda (cons parameters body))) (define (define-variable! var val env) (let ((frame (first-frame env))) (define (scan vars vals) (cond ((null? vars) (add-binding-to-frame! var val frame)) ((eq? var (car vars)) (set-car! vals val)) (else (scan (cdr vars) (cdr vals))))) (scan (frame-variables frame) (frame-values frame)))) (define (add-binding-to-frame! var val frame) (set-car! frame (cons var (car frame))) (set-cdr! frame (cons val (cdr frame)))) other definitions: (define (tagged-list? exp tag) (if (pair? exp) (eq? (car exp) tag) false)) (define false #f) (define true (not false)) (define (true? x) (not (eq? x false))) (define (false? x) (eq? x false)) .ז.ת
© Copyright 2026 Paperzz