diff --git a/csp/search.rkt b/csp/search.rkt index 758e5d7d..f8578d02 100644 --- a/csp/search.rkt +++ b/csp/search.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require racket/class) +(require racket/class racket/match) (provide (all-defined-out)) @@ -12,7 +12,7 @@ (class object% (super-new) - (init-field initial [goal null]) + (init-field initial [goal #f]) ;; The constructor specifies the initial state, and possibly a goal ;; state, if there is a unique goal. Your subclass's constructor can add ;; other arguments. @@ -42,3 +42,53 @@ ;; and related algorithms try to maximize this value. )) +(require describe) + +(define Node + #| A node in a search tree. Contains a pointer to the parent (the node + that this is a successor of) and to the actual state for this node. Note + that if a state is arrived at by two paths, then there are two nodes with + the same state. Also includes the action that got us to this state, and + the total path_cost (also known as g) to reach the node. Other functions + may add an f and h value; see best_first_graph_search and astar_search for + an explanation of how the f and h values are handled. You will not need to + subclass this class. +|# + + (class* object% (printable<%>) + (super-new) + + (init-field state [parent #f] [action #f] [path_cost 0]) + (field [depth (if parent (add1 (get-field depth parent)) 0)]) + ;; Create a search tree Node, derived from a parent by an action. + + (define (repr) (format "" (get-field state this))) + (define/public (custom-print out quoting-depth) (print (repr) out)) + (define/public (custom-display out) (displayln (repr) out)) + (define/public (custom-write out) (write (repr) out)) + + (define/public (path) + ;; Create a list of nodes from the root to this node. + (let ([parent (get-field parent this)]) + (cons this + (if (not parent) + null + (send parent path))))) + + (define/public (expand problem) + ;; Return a list of nodes reachable from this node. + (for/list ([action-state-pair (in-list (send problem successor state))]) + (match-define (cons act next) action-state-pair) + (new Node [state next][parent this][action act] + [path_cost (send problem path_cost path_cost state act next)]))) + )) + +(module+ main + (require racket/format) + (define gp (new Node [state 'grandparent])) + (define p (new Node [state 'parent][parent gp])) + (get-field state p) + (get-field depth p) + (define c (new Node [state 'child] [parent p])) + (get-field depth c) + (send c path)) \ No newline at end of file