-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcse.scm
152 lines (107 loc) · 3.88 KB
/
cse.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
(print-gensym #f)
(define listOflist?
(lambda (expr)
(ormap (lambda (x) (and (list? x) (not (quote? x) ))) expr)))
(define ^quote?
(lambda (tag)
(lambda (e)
(and (pair? e)
(eq? (car e) tag)
(pair? (cdr e))
(null? (cddr e))))))
(define quote? (^quote? 'quote))
(define count-occurrences
(lambda (x ls)
(cond
((equal? x ls) 1)
((null? ls) 0)
((not (list? ls) ) 0)
(else (fold-left + 0 (map (lambda (smallerLs)(count-occurrences x smallerLs)) ls))))))
(define reallyHasDups?
(lambda (arg lst)
(cond ((null? lst) #f)
((not (list? lst)) #f)
((not (listOflist? lst)) #f)
((not (list? arg) ) #f)
((quote? arg ) #f)
((> (count-occurrences arg lst) 1) arg)
(else (reallyHasDups? arg (cdr lst)))
)))
(define hasDups?
(lambda (orignalList lst)
; (display lst) (newline)
(cond ((not (list? lst) ) #f)
((null? lst ) #f)
((and (list? (car lst)) (not (quote? (car lst) )) (listOflist? (car lst)))
(hasDups? orignalList (car lst) ))
((reallyHasDups? (car lst) orignalList) (reallyHasDups? (car lst) orignalList))
(else (hasDups? orignalList (cdr lst))))))
(define setChangedList
(lambda (bigExp multyExp optimizeExp)
(cond
((null? bigExp) bigExp)
((equal? bigExp multyExp) optimizeExp)
((not (list? bigExp)) bigExp)
(else (map (lambda (exp) (setChangedList exp multyExp optimizeExp)) bigExp)))))
(define setChanges
(lambda (changes multy gensymVar)
(cons (list gensymVar multy) changes)))
(define optimizeList
(lambda (orignalList changedList changes)
(if (hasDups? changedList changedList)
(let ((gensymVar (gensym))
(multy (hasDups? changedList changedList)))
(optimizeList orignalList
(setChangedList changedList multy gensymVar)
(setChanges changes multy gensymVar )))
(cons changes changedList))
))
(define best?
(lambda (arg lst)
(let ((count (count-occurrences arg lst) ))
(= count 2))
) )
(define getGen
(lambda (changes) (caar changes) ))
(define getSecondElment
(lambda (opt) (cadr opt )))
(define combineList
(lambda lst
lst))
(define removeChange
(lambda (opt firstChange)
;setChangedList
(let (( ans (setChangedList opt (car firstChange) (getSecondElment firstChange ))))
( combineList (filter (lambda (pair) (not (equal? (car pair) (getSecondElment pair)))) (car ans)) (getSecondElment ans)))))
;;;
(define bestFit
(lambda (changes changedList)
(let ((opt (list changes changedList)) )
(if (null? changes)
opt ;we found the bestFit
(if (best? (getGen changes) opt) ; there is an unnecessary optimization
;make new optimization
(let* ((betterOpt (removeChange opt (car changes ) )))
;(display betterOpt) (newline)
(bestFit (car betterOpt) (getSecondElment betterOpt) ))
;else ,Check if rest of changes have an unnecessary optimization
(let* ((bestOpt (bestFit (cdr changes) changedList ))
(first (append (list (car changes ) ) (car bestOpt)))
(sec (getSecondElment bestOpt)))
(list first sec )))))
))
;;
(define cse
(lambda (expr)
(let ((originExp expr)
(changes '()))
(let* ((opt (optimizeList originExp originExp changes))
(vars (reverse (car opt)))
(newExp (cdr opt))
(bestOpt (bestFit vars newExp )))
(if (equal? originExp newExp)
originExp ;return not changed
(if (= 1 (length (car bestOpt)))
`(let ,(car bestOpt) ,(getSecondElment bestOpt))
`(let* ,(car bestOpt) ,(getSecondElment bestOpt))) ))
)))