Download 5-Grammars for Inductive Data

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Computer Science 312
Inductive Data and BNF Grammars
Pairs (aka Dotted pairs)
(cons 3 ())
-> (3)
(cdr (cons 3 ()) -> ()
(cons 3 2)
-> (3 . 2)
(cdr (cons 3 2)) -> 2
•  A dotted pair contains two parts: a car and a cdr
•  A list is a dotted pair whose cdr is another list
•  The dot is suppressed when a list is printed
•  pair? is the type predicate for pairs, which include lists
Inductive Sets of Data
•  Recall the definition of a list:
– () is a list
–  If L is a list and A is any object,
then (cons A L) is a list
•  More generally:
–  Define a simplest element
–  Define remaining elements by induction
Backus-Nauer Form (BNF)
•  Simplifies description of inductive data types
<list-of-numbers> ::= ()
<list-of-numbers> ::= (<number> . <list-of-numbers>)
Where (a . b) is like (cons a b)
•  Consists of
–  Terminal symbols: 0 ) . (
–  Non-terminal symbols: <list-of-numbers>
–  Productions: <list-of-numbers> ::= ()
BNF: Metasymbols
•  Disjunction (this or that): |
<list-of-numbers> ::= () | (<number> . <list-of-numbers>)
•  Kleene Star (zero or more): {}*
<list-of-numbers> ::= ({<number>}*)
•  Kleene Plus: (one or more): {}+
<non-empty-list-of-numbers> ::= ({<number>}+)
Write Programs
to Manipulate the Data
<list-of-numbers> ::= () | (<number> . <list-of-numbers>)
(define list-of-numbers?
(lambda (lst)
(if (null? lst)
#t
(if (not (number? (car lst)))
#f
(list-of-numbers (cdr lst))))))
Type recognition predicate
Write Programs
to Manipulate the Data
<list-of-numbers> ::= () | (<number> . <list-of-numbers>)
(define list-of-numbers?
(lambda (lst)
(if (null? lst)
#t
(and (number? (car lst))
(list-of-numbers (cdr lst))))))
and and or are special forms that do short-circuit evaluation
Write Programs
to Manipulate the Data
<list-of-numbers> ::= () | (<number> . <list-of-numbers>)
(define contains?
(lambda (lst num)
(if (null? lst)
#f
(or (= (car lst) num))
(contains? (cdr lst) num)))))
and and or are special forms that do short-circuit evaluation
Write Programs
to Manipulate the Data
<list-of-numbers> ::= () | (<number> . <list-of-numbers>)
(define sum
(lambda (lst)
(if (null? lst)
0
(+ (car lst)
(sum (cdr lst))))))
When writing a program based on structural induction, the
structure of the program should be patterned after the
structure of the data.
Write Programs
to Manipulate the Data
<list-of-numbers> ::= () | (<number> . <list-of-numbers>)
(define our-copy
(lambda (lst)
(if (null? lst)
()
(cons (car lst)
(our-copy (cdr lst))))))
A very common pattern: build and return a list that
reflects the structure of the input list
Write Programs
to Manipulate the Data
<list-of-numbers> ::= () | (<number> . <list-of-numbers>)
(define our-map
(lambda (proc lst)
(if (null? lst)
()
(cons (proc (car lst))
(our-map proc (cdr lst))))))
Mapping: apply a procedure to each element and return a
list of the results
(our-map abs '(2 3 -5 9 -22)) -> (2 3 5 9 22)
Write Programs
to Manipulate the Data
<list-of-numbers> ::= () | (<number> . <list-of-numbers>)
(define remove-first
(lambda (lst val)
(if (null? lst)
()
(if (= (car lst) val)
(cdr lst)
(cons (car lst)
(remove-first (cdr lst) val))))))
Look for the first instance of val and drop it out
(remove-first '(2 3 4 3) 3) -> (2 4 3)
Write Programs
to Manipulate the Data
<list-of-numbers> ::= () | (<number> . <list-of-numbers>)
(define remove-all
(lambda (lst val)
(if (null? lst)
()
(if (= (car lst) val)
??
(cons (car lst)
??
Look for remaining instances of val and drop them out
(remove-all '(2 3 4 3) 3) -> (2 4)
Write Programs
to Manipulate the Data
<s-list> ::= ({<symbol> | <s-list>}*)
(), (a b), ((a b) c), etc.
(define s-list?
(lambda (lst)
(if (null? lst)
#t
(if (symbol? (car
(s-list? (cdr
(and (s-list?
(s-list?
Allows for nested lists of symbols
lst))
lst))
(car lst))
(cdr lst))))))
Skip over symbols and continue testing
or
Test both the car and the cdr
Write Programs
to Manipulate the Data
<s-list> ::= ({<symbol> | <s-list>}*)
(), (a b), ((a b) c), etc.
(define remove-all (lambda (lst val)
(if (null? lst)
()
(if (symbol? (car lst))
(if (eqv? (car lst) val)
(remove (cdr lst))
(cons (car lst) (remove (cdr lst) val)))
(cons (remove-all (car lst) val)
(remove-all (cdr lst) val))))))
(remove-all ‘((a b) c a d (((a))))) -> ((b) c d ((()))))
car/cdr recursion is a common pattern
Equality in Scheme
•  = is used with numbers
•  string=? is used for strings
•  string-ci=? for strings but ignores case
•  eqv? is used for any atoms
•  equals is used with lists, etc.
Write Programs
to Manipulate the Data
<bin-tree> ::= {<number> | (<symbol> <bin-tree> <bin-tree>)
2, (a 2 3 ), (a (b 2 3) (c 4 5)), etc.
2
a
a
2
c
b
3
2
3
4
5
Write Programs
to Manipulate the Data
<bin-tree> ::= {<number> | (<symbol> <bin-tree> <bin-tree>)
2, (a 2 3 ), (a (b 2 3) (c 4 5)), etc.
(define bin-tree?
(lambda (exp)
(or (number? exp)
(and (symbol? (car exp))
(bin-tree? (cadr exp))
(bin-tree? (caddr exp))))))