diff --git a/csp/search.rkt b/csp/search.rkt index a48d6a62..758e5d7d 100644 --- a/csp/search.rkt +++ b/csp/search.rkt @@ -1,3 +1,44 @@ #lang racket/base +(require racket/class) + +(provide (all-defined-out)) + +(define Problem + ;; The abstract class for a formal problem. You should subclass this and + ;; implement the method successor, and possibly __init__, goal_test, and + ;; path_cost. Then you will create instances of your subclass and solve them + ;; with the various search functions. + + (class object% + (super-new) + + (init-field initial [goal null]) + ;; 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. + + (abstract successor) + ;; Given a state, return a sequence of (action, state) pairs reachable + ;; from this state. If there are many successors, consider an iterator + ;; that yields the successors one at a time, rather than building them + ;; all at once. Iterators will work fine within the framework. + + (define/public (goal_test state) + ;; Return True if the state is a goal. The default method compares the + ;; state to self.goal, as specified in the constructor. Implement this + ;; method if checking against a single self.goal is not enough. + (and (equal? state goal) #t)) + + (define/public (path_cost c state1 action state2) + ;; Return the cost of a solution path that arrives at state2 from + ;; state1 via action, assuming cost c to get up to state1. If the problem + ;; is such that the path doesn't matter, this function will only look at + ;; state2. If the path does matter, it will consider c and maybe state1 + ;; and action. The default method costs 1 for every step in the path. + (add1 c)) + + (abstract value) + ;; For optimization problems, each state has a value. Hill-climbing + ;; and related algorithms try to maximize this value. + )) -(provide (all-defined-out)) \ No newline at end of file