;;; prototype of system to simulate p2p interactions ;;; system consists of files, friends, and servers ;;; a file is a tagged structure that includes a name and some data (define (tagged-list? lst tag) (and (pair? lst) (eq? (car lst) tag))) (define file-tag 'file) (define (make-file name data) ;; name should be a string, ;; data is some other information, in some format (list file-tag name data)) (define (file? f) (tagged-list? f file-tag)) (define file-name cadr) (define file-data caddr) ;;; a friend is a person, who has a name, a location (which is a server) ;;; a set of friends, and a who-has data structure, that will keep ;;; track of which friends have what files ;;; ;;; a friend will be represented as a tagged data structure (define friend-tag 'friend) (define (make-friend name server) ;; a friend's name is a symbol (list friend-tag name server '() ;; list of other friends '() ;; a data structure of files owned by other friends )) (define (friend? obj) (tagged-list? obj friend-tag)) ;;;these selectors need to be defined ;(define (friend-name f) 'to-fill-in) ;(define (friend-server f) 'to-fill-in) ;(define (friend-others f) 'to-fill-in) ;(define (friend-who-has f) 'to-fill-in) ;;; we need a way of adding a friend to our list of friends (define (add-friend me friend) (if (and (friend? friend) (friend? me)) (set-car! (cdddr me) (cons friend (friend-others me))) (error "not a friend"))) (define (friend-set-who-has! friend data) (if (friend? friend) (set-car! (cddddr friend) data) (error "not a friend"))) ;;; base object is a server that has a list of files (stored by name) ;;; ;;; a server will be represented by a procedure ;;; base object (define (make-server name) (let ((files '())) (lambda (action) (cond ((eq? action 'name) name) ((eq? action 'add-file) (lambda (new) (set! files (cons new files)))) ((eq? action 'have-file?) (lambda (name) (lookup-file name files))) ((eq? action 'all-files) files) (else (error "don't know how to do" action)))))) (define (lookup-file filename data) ;; filename should be a string, ;; data is a data structure that represents the set of file abstractions ;; for now, we will assume it is a list (if (null? data) false (if (string=? filename (file-name (car data))) true (lookup-file filename (cdr data))))) ;; procedure for looking for a file of a given name (define (I-want-file name me) ;;; name is a file name, as a string ;;; me is a person or friend (let ((where-am-I (friend-server me))) (display "I am here ") (display (where-am-i 'name)) (newline) (let ((there? ((where-am-I 'have-file?) name))) (if there? (begin (display "I have the file online") (newline) 'I-HAVE-IT) (let ((friends (friend-others me))) (display "The file is not online.") (newline) (display "these are my friends ") (display (map friend-name friends)) (newline) (search name friends)))))) ;; you need to write search (define (I-want-file-new name me) ;;; name is a file name, as a string ;;; me is a person or friend (let ((where-am-I (friend-server me))) (display "I am here ") (display (where-am-i 'name)) (newline) (let ((there? ((where-am-I 'have-file?) name))) (if there? (begin (display "I have the file online") (newline) 'I-HAVE-IT) (let ((friends (friend-others me))) (display "The file is not online.") (newline) (display "these are my friends ") (display (map friend-name friends)) (newline) (search-new name friends me)))))) ;;; you need to write search-new ;;; binary tree representation of files (define (make-node data left right) ;; data here is an a-list (list data left right)) ;; we will use an empty list to denote an empty tree (define empty-node '()) (define (empty-node? n) (null? n)) (define (node-data node) (car node)) (define (node-left node) (cadr node)) (define (node-right node) (caddr node)) ;;; here is one more version of the search process (define (I-want-file-with-record name me) (let ((where-am-I (friend-server me))) (display "I am here ") (display (where-am-i 'name)) (newline) (let ((there? ((where-am-I 'have-file?) name))) (if there? (begin (display "I have the file online") (newline) 'I-HAVE-IT) (let ((known (retrieve name (friend-who-has me)))) (if known (begin (display "I have already found a friend who has it") (newline) 'MY-FRIENDS-HAVE-IT) (let ((friends (friend-others me))) (display "Checking with my friends ") (display (map friend-name friends)) (newline) (search-new name friends me)))))))) ;; you need to write retrieve