61a lecture 13
play

61A Lecture 13 {'Dem': 0} Wednesday, September 28 2 Limitations - PDF document

Dictionaries 61A Lecture 13 {'Dem': 0} Wednesday, September 28 2 Limitations on Dictionaries Implementing Dictionaries def make_dict(): """Return a functional implementation of a dictionary.""" Dictionaries are


  1. Dictionaries 61A Lecture 13 {'Dem': 0} Wednesday, September 28 2 Limitations on Dictionaries Implementing Dictionaries def make_dict(): """Return a functional implementation of a dictionary.""" Dictionaries are unordered collections of key-value pairs. records = [] def getitem(key): Dictionaries do have two restrictions: for k, v in records: if k == key: return v • A key of a dictionary cannot be an object of a mutable def setitem(key, value): Question: Do we need a built-in type. nonlocal statement here? for item in records: if item[0] == key: item[1] = value • Two keys cannot be equal . There can be at most one value for return a given key. records.append([key, value]) def dispatch(message, key=None, value=None): if message == 'getitem': This first restriction is tied to Python's underlying return getitem(key) implementation of dictionaries. elif message == 'setitem': setitem(key, value) elif message == 'keys': return tuple(k for k, _ in records) The second restriction is an intentional consequence of the elif message == 'values': dictionary abstraction. return tuple(v for _, v in records) Demo return dispatch 3 4 Message Passing Dispatch Dictionaries An approach to organizing the relationship among different Enumerating different messages in a conditional statement pieces of a program isn't very convenient: ! Equality tests are repetitive Different objects pass messages to each other ! We can't add new messages without writing new code • What is your fourth element? A dispatch dictionary has messages as keys and functions (or • Change your third element to this new value. (please) data objects) as values. Dictionaries handle the message look-up logic; we concentrate Encapsulates the behavior of all on implementing useful behavior. operations on a piece of data within one function that responds to different messages. Important historical interest: the Demo message passing approach strongly influenced object-oriented programming (next lecture). In Javascript, all objects are just dictionaries 5 6

  2. Example: Constraint Programming A Constraint Network for Temperature Conversion a + b = c Combination idea: All intermediate quantities have values too. p * v = n * k * t a = c - b u 9 * c = 5 * (f - 32) u v b = c - a Both sides equal: 9 * celsius = 5 * ( fahrenheit - 32) they must be the same quantity Algebraic equations are declarative . They describe how This quantity This quantity different quantities relate to one another. relates directly relates directly to celsius to fahrenheit Python functions are procedural . They describe how to compute a particular result from a particular set of inputs. Constraint programming: v a a a celsius u ! We define the relationship between quantities * c c * + c fahrenheit ! We provide values for the "known" quantities b b b w x y ! The system computes values for the "unknown" quantities 5 32 9 Challenge : We want a general means of combination. 7 8 Anatomy of a Constraint Constructing a Constraint Network def make_converter(celsius, fahrenheit): """Make a temperature conversion network.""" a celsius Constraints compute u u, v, w, x, y = [make_connector() for _ in range(5)] * c values for "unknown" multiplier(celsius, w, u) w b connectors Blue names are multiplier(v, x, u) "connectors" adder(v, y, fahrenheit) constant(w, 9) Boxes are constant(x, 5) "constraints" constant(y, 32) v • Connectors represent quantities that have values. a a a celsius u * c c * + c fahrenheit � • Constraints spread information among connectors. b b b w x y • A constraint can receive two messages from its connectors: 5 32 9 � ! ' new_val ' indicates that some connector that is connected � to the constraint has a new value. celsius = make_connector('Celsius') ! ' forget ' indicates that some connector that is connected fahrenheit = make_connector('Fahrenheit') to the constraint has forgotten its value. Demo make_converter(celsius, fahrenheit) 9 10 The Messages of a Connector Implementing an Adder Constraint def adder_constraint(a, b, c): """The constraint that a + b = c. connector = make_connector('Celsius') >>> a, b, c = [make_connector(name) for name in ('a', 'b', 'c')] >>> constraint = adder_constraint(a, b, c) connector[ 'set_val' ](source, value) indicates that the >>> a['set_val']('user', 2) a = 2 source is requesting the connector to set its current >>> b['set_val']('user', 3) value to value. b = 3 c = 5 """ connector[ 'has_val' ]() returns whether the connector """ def new_value(): def new_value(): � already has a value. av, bv, cv = [connector['has_val']() for connector in (a, b, c)] # We will implement this function momentarily! a['set_val'](constraint, c['val'] � b['val']) connector[ 'val' ] is the current value of the connector. def forget_value(): � � for connector in (a, b, c): connector['forget'](constraint) � connector[ 'forget' ](source) tells the connector that the � source is requesting it to forget its value. constraint = {'new_val': new_value, 'forget': forget_value} for connector in (a, b, c): connector[ 'connect' ](source) tells the connector to connector['connect'](constraint) participate in a new constraint, the source. return constraint 11 12

  3. � � � � � � � � � Generalizing to a Multiplication Constraint Implementing a Connector def make_connector(name=None): Connectors Relations """ """A connector between constraints. informant = None constraints = [] def make_ternary_constraint(a, b, c, ab, ca, cb): constraints = [] def set_value(source, value): def set_value(source, value): """The constraint that ab(a,b)=c and ca(c,a)=b and cb(c,b)=a.""" nonlocal informant def new_value(): val = connector['val'] av, bv, cv = [connector['has_val']() for connector in (a, b, c)] if val is None: av, bv, cv = [connector['has_val']() for connector in (a, b, c)] if av and bv: informant, connector['val'] = source, value if av and bv: if name is not None: c['set_val'](constraint, ab(a['val'], b['val'])) print(name, '=', value) c['set_val'](constraint, ab(a['val'], b['val'])) elif av and cv: inform_all_except(source, 'new_val', constraints) elif av and cv: else : b['set_val'](constraint, ac(c['val'], a['val'])) if val != value: print('Contradiction detected:', val, 'vs', value) print('Contradiction detected:', val, 'vs', value) elif bv and cv: def forget_value(source): a['set_val'](constraint, cb(c['val'], b['val'])) def forget_value(source): nonlocal informant def forget_value(): if informant == source: informant, connector['val'] = None, None from operator import add, sub, mul, truediv if name is not None: print(name, 'is forgotten') def adder(a, b, c): inform_all_except(source, 'forget', constraints) """The constraint that a + b = c.""" inform_all_except(source, 'forget', constraints) connector = {'val': None, return make_ternary_constraint(a, b, c, add, sub, sub) connector = {'val': None, 'set_val': set_value, 'forget': forget_value, def multiplier(a, b, c): 'has_val': lambda : connector['val'] is not None, """The constraint that a * b = c.""" 'connect': lambda source: constraints.append(source)} return make_ternary_constraint(a, b, c, mul, truediv, truediv) return connector 13 14

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend