shen-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +0 -0
  3. data/Gemfile +6 -0
  4. data/Gemfile.lock +20 -0
  5. data/MIT_LICENSE.txt +26 -0
  6. data/README.md +94 -0
  7. data/bin/shen_test_suite.rb +9 -0
  8. data/bin/srrepl +23 -0
  9. data/lib/kl.rb +7 -0
  10. data/lib/kl/absvector.rb +12 -0
  11. data/lib/kl/compiler.rb +253 -0
  12. data/lib/kl/cons.rb +51 -0
  13. data/lib/kl/empty_list.rb +12 -0
  14. data/lib/kl/environment.rb +123 -0
  15. data/lib/kl/error.rb +4 -0
  16. data/lib/kl/internal_error.rb +7 -0
  17. data/lib/kl/lexer.rb +186 -0
  18. data/lib/kl/primitives/arithmetic.rb +60 -0
  19. data/lib/kl/primitives/assignments.rb +18 -0
  20. data/lib/kl/primitives/booleans.rb +17 -0
  21. data/lib/kl/primitives/error_handling.rb +13 -0
  22. data/lib/kl/primitives/generic_functions.rb +22 -0
  23. data/lib/kl/primitives/lists.rb +21 -0
  24. data/lib/kl/primitives/streams.rb +38 -0
  25. data/lib/kl/primitives/strings.rb +55 -0
  26. data/lib/kl/primitives/symbols.rb +17 -0
  27. data/lib/kl/primitives/time.rb +17 -0
  28. data/lib/kl/primitives/vectors.rb +30 -0
  29. data/lib/kl/reader.rb +40 -0
  30. data/lib/kl/trampoline.rb +14 -0
  31. data/lib/shen_ruby.rb +7 -0
  32. data/lib/shen_ruby/version.rb +3 -0
  33. data/shen-ruby.gemspec +26 -0
  34. data/shen/README.txt +17 -0
  35. data/shen/lib/shen_ruby/shen.rb +124 -0
  36. data/shen/license.txt +34 -0
  37. data/shen/release/benchmarks/N_queens.shen +45 -0
  38. data/shen/release/benchmarks/README.shen +14 -0
  39. data/shen/release/benchmarks/benchmarks.shen +56 -0
  40. data/shen/release/benchmarks/bigprog +2173 -0
  41. data/shen/release/benchmarks/br.shen +13 -0
  42. data/shen/release/benchmarks/einstein.shen +33 -0
  43. data/shen/release/benchmarks/heatwave.gif +0 -0
  44. data/shen/release/benchmarks/interpreter.shen +219 -0
  45. data/shen/release/benchmarks/picture.jpg +0 -0
  46. data/shen/release/benchmarks/plato.jpg +0 -0
  47. data/shen/release/benchmarks/powerset.shen +10 -0
  48. data/shen/release/benchmarks/prime.shen +10 -0
  49. data/shen/release/benchmarks/short.shen +129 -0
  50. data/shen/release/benchmarks/text.txt +68 -0
  51. data/shen/release/k_lambda/core.kl +1002 -0
  52. data/shen/release/k_lambda/declarations.kl +1021 -0
  53. data/shen/release/k_lambda/load.kl +94 -0
  54. data/shen/release/k_lambda/macros.kl +479 -0
  55. data/shen/release/k_lambda/prolog.kl +1309 -0
  56. data/shen/release/k_lambda/reader.kl +1058 -0
  57. data/shen/release/k_lambda/sequent.kl +556 -0
  58. data/shen/release/k_lambda/sys.kl +582 -0
  59. data/shen/release/k_lambda/t-star.kl +3493 -0
  60. data/shen/release/k_lambda/toplevel.kl +223 -0
  61. data/shen/release/k_lambda/track.kl +208 -0
  62. data/shen/release/k_lambda/types.kl +455 -0
  63. data/shen/release/k_lambda/writer.kl +108 -0
  64. data/shen/release/k_lambda/yacc.kl +280 -0
  65. data/shen/release/test_programs/Chap13/problems.txt +26 -0
  66. data/shen/release/test_programs/README.shen +53 -0
  67. data/shen/release/test_programs/TinyLispFunctions.txt +16 -0
  68. data/shen/release/test_programs/TinyTypes.shen +55 -0
  69. data/shen/release/test_programs/binary.shen +24 -0
  70. data/shen/release/test_programs/bubble_version_1.shen +28 -0
  71. data/shen/release/test_programs/bubble_version_2.shen +22 -0
  72. data/shen/release/test_programs/calculator.shen +21 -0
  73. data/shen/release/test_programs/cartprod.shen +23 -0
  74. data/shen/release/test_programs/change.shen +25 -0
  75. data/shen/release/test_programs/classes-defaults.shen +94 -0
  76. data/shen/release/test_programs/classes-inheritance.shen +100 -0
  77. data/shen/release/test_programs/classes-typed.shen +74 -0
  78. data/shen/release/test_programs/classes-untyped.shen +46 -0
  79. data/shen/release/test_programs/depth_.shen +14 -0
  80. data/shen/release/test_programs/einstein.shen +33 -0
  81. data/shen/release/test_programs/fruit_machine.shen +46 -0
  82. data/shen/release/test_programs/interpreter.shen +219 -0
  83. data/shen/release/test_programs/metaprog.shen +85 -0
  84. data/shen/release/test_programs/minim.shen +193 -0
  85. data/shen/release/test_programs/mutual.shen +11 -0
  86. data/shen/release/test_programs/n_queens.shen +45 -0
  87. data/shen/release/test_programs/newton_version_1.shen +33 -0
  88. data/shen/release/test_programs/newton_version_2.shen +24 -0
  89. data/shen/release/test_programs/parse.prl +14 -0
  90. data/shen/release/test_programs/parser.shen +52 -0
  91. data/shen/release/test_programs/powerset.shen +10 -0
  92. data/shen/release/test_programs/prime.shen +10 -0
  93. data/shen/release/test_programs/proof_assistant.shen +81 -0
  94. data/shen/release/test_programs/proplog_version_1.shen +25 -0
  95. data/shen/release/test_programs/proplog_version_2.shen +27 -0
  96. data/shen/release/test_programs/qmachine.shen +67 -0
  97. data/shen/release/test_programs/red-black.shen +55 -0
  98. data/shen/release/test_programs/search.shen +56 -0
  99. data/shen/release/test_programs/semantic_net.shen +44 -0
  100. data/shen/release/test_programs/spreadsheet.shen +35 -0
  101. data/shen/release/test_programs/stack.shen +27 -0
  102. data/shen/release/test_programs/streams.shen +20 -0
  103. data/shen/release/test_programs/strings.shen +59 -0
  104. data/shen/release/test_programs/structures-typed.shen +71 -0
  105. data/shen/release/test_programs/structures-untyped.shen +42 -0
  106. data/shen/release/test_programs/tests.shen +294 -0
  107. data/shen/release/test_programs/types.shen +11 -0
  108. data/shen/release/test_programs/whist.shen +240 -0
  109. data/shen/release/test_programs/yacc.shen +136 -0
  110. data/spec/kl/cons_spec.rb +12 -0
  111. data/spec/kl/environment_spec.rb +306 -0
  112. data/spec/kl/lexer_spec.rb +149 -0
  113. data/spec/kl/primitives/generic_functions_spec.rb +29 -0
  114. data/spec/kl/primitives/symbols_spec.rb +21 -0
  115. data/spec/kl/reader_spec.rb +36 -0
  116. data/spec/spec_helper.rb +2 -0
  117. metadata +189 -0
@@ -0,0 +1,42 @@
1
+ (define defstruct
2
+ Name Attributes -> (let Selectors (selectors Name Attributes)
3
+ Constructor (constructor Name Attributes)
4
+ Recognisor (recognisor Name)
5
+ Name))
6
+
7
+ (define selectors
8
+ Name Attributes -> (map (/. A (selector Name A)) Attributes))
9
+
10
+ (define selector
11
+ Name Attribute
12
+ -> (let SelectorName (concat Name (concat - Attribute))
13
+ (eval [define SelectorName
14
+ (protect Structure) -> [let (protect LookUp) [assoc Attribute (protect Structure)]
15
+ [if [empty? (protect LookUp)]
16
+ [error "~A is not an attribute of ~A.~%"
17
+ Attribute Name]
18
+ [tail (protect LookUp)]]]])))
19
+
20
+ (define constructor
21
+ Name Attributes
22
+ -> (let ConstructorName (concat make- Name)
23
+ Parameters (params Attributes)
24
+ (eval [define ConstructorName |
25
+ (append Parameters
26
+ [-> [cons [cons structure Name]
27
+ (make-association-list Attributes
28
+ Parameters)]])])))
29
+
30
+ (define params
31
+ [] -> []
32
+ [_ | Attributes] -> [(gensym (protect X)) | (params Attributes)])
33
+
34
+ (define make-association-list
35
+ [] [] -> []
36
+ [A | As] [P | Ps] -> [cons [cons A P] (make-association-list As Ps)])
37
+
38
+ (define recognisor
39
+ Name -> (let RecognisorName (concat Name ?)
40
+ (eval [define RecognisorName
41
+ [cons [cons structure Name] _] -> true
42
+ _ -> false])))
@@ -0,0 +1,294 @@
1
+ (maxinferences 10000000000)
2
+
3
+ (report prolog-tests
4
+ (defprolog f
5
+ a <--;) f
6
+ (prolog? (f a)) true
7
+ (defprolog g
8
+ a <-- ! (f b);
9
+ X <-- (f a);) g
10
+ (prolog? (g a)) false
11
+ (prolog? (g b)) true
12
+ (defprolog mem
13
+ X [X | _] <--;
14
+ X [Y | Z] <-- (mem X Z);) mem
15
+ (prolog? (mem 1 [X | 2]) (return X)) 1
16
+ (defprolog app
17
+ [] X X <--;
18
+ [X | Y] W [X | Z] <-- (app Y W Z);) app
19
+ (defprolog rev
20
+ [] [] <--;
21
+ [X | Y] Z <-- (rev Y W) (app W [X] Z);) rev
22
+ (prolog? (rev [1 2] X) (return X)) [2 1]
23
+ (load "einstein.shen") loaded
24
+ (prolog? (einsteins_riddle X) (return X)) german
25
+ (defprolog enjoys
26
+ willi X <-- (likes mark X);
27
+ mark chocolate <--;
28
+ mark tea <--;) enjoys
29
+ (prolog? (enjoys mark X) (return X)) chocolate
30
+ (defprolog fads
31
+ X <-- (findall Y [enjoys X Y] Friends) (return Friends);) fads
32
+ (prolog? (fads mark)) [tea chocolate]
33
+ (defprolog prop
34
+ A C <-- (proph [[~ C] | A]);) prop
35
+ (defprolog proph
36
+ A <-- (mem [~ P] A) (mem P A) !;
37
+ A <-- (consistent A) ! (when false);
38
+ (mode [[P & Q] | A] -) <-- ! (proph [P Q | A]);
39
+ (mode [[P <=> Q] | A] -) <-- ! (proph [[P => Q] [Q => P] | A]);
40
+ (mode [[P => Q] | A] -) <-- ! (proph [[[~ P] v Q] | A]);
41
+ (mode [[~ [P v Q]] | A] -) <-- ! (proph [[~ P] [~ Q] | A]);
42
+ (mode [[~ [P & Q]] | A] -) <-- ! (proph [[[~ P] v [~ Q]] | A]);
43
+ (mode [[~ [P => Q]] | A] -) <-- ! (proph [P [~ Q] | A]);
44
+ (mode [[~ [P <=> Q]] | A] -) <-- ! (proph [[~ [[P => Q] v [~ [Q => P]]]] | A]);
45
+ (mode [[P & Q] | A] -) <-- ! (proph [P Q | A]);
46
+ (mode [[P v Q] | A] -) <-- ! (proph [P | A]) ! (proph [Q | A]);
47
+ (mode [P | Ps] -) <-- (app Ps [P] Qs) ! (proph Qs);) proph
48
+ (defprolog consistent
49
+ [] <--;
50
+ [P | Ps] <-- (when (symbol? P)) ! (consistent Ps);
51
+ [[~ P] | Ps] <-- (when (symbol? P)) ! (consistent Ps);) consistent
52
+ (defprolog app
53
+ [] X X <--;
54
+ (mode [X | Y] -) W [X | Z] <-- (app Y W Z);) app
55
+ (defprolog mem
56
+ X (mode [X | _] -) <--;
57
+ X (mode [_ | Y] -) <-- (mem X Y);) mem
58
+ (prolog? (prop [] [p <=> p])) true
59
+ (defprolog mapit
60
+ _ [] [] <--;
61
+ Pred [X | Y] [W | Z] <-- (call [Pred X W]) (mapit Pred Y Z);) mapit
62
+ (defprolog consit
63
+ X [1 X] <--;) consit
64
+ (prolog? (mapit consit [1 2 3] Out) (return Out))
65
+ [[1 1] [1 2] [1 3]]
66
+ (defprolog different
67
+ X Y <-- (~ [identical X Y]);) different
68
+ (defprolog ~
69
+ P <-- (call P) ! (when false);
70
+ _ <--;) ~
71
+ (prolog? (different a b)) true
72
+ (prolog? (different a a)) false
73
+ (defprolog likes
74
+ john X <-- (tall X) (pretty X);) likes
75
+ (defprolog tall
76
+ mary <--;) tall
77
+ (defprolog pretty
78
+ mary <--;) pretty
79
+ (prolog? (likes john Who) (return Who)) mary
80
+ (load "parse.prl") loaded
81
+ (prolog? (pparse ["the" + ["boy" + "jumps"]]
82
+ [[s = [np + vp]]
83
+ [np = [det + n]]
84
+ [det = "the"]
85
+ [n = "girl"]
86
+ [n = "boy"]
87
+ [vp = vintrans]
88
+ [vp = [vtrans + np]]
89
+ [vintrans = "jumps"]
90
+ [vtrans = "likes"]
91
+ [vtrans = "loves"]])) true)
92
+
93
+ \* (report "FPQi chapter 2"
94
+ (load "fruit_machine.shen") loaded
95
+ (do (print (fruit-machine start)) ok) ok) *\
96
+
97
+
98
+ (report "FPQi chapter 4"
99
+ (load "cartprod.shen") loaded
100
+ (cartesian-product [1 2 3] [1 2 3])
101
+ [[1 1] [1 2] [1 3] [2 1] [2 2] [2 3] [3 1] [3 2] [3 3]]
102
+ (load "powerset.shen") loaded
103
+ (powerset [1 2 3]) [[1 2 3] [1 2] [1 3] [1] [2 3] [2] [3] []])
104
+
105
+ (do (set *sprd* )
106
+ (nl 2))
107
+
108
+ (report "FPQi chapter 5"
109
+
110
+ (load "bubble_version_1.shen") loaded
111
+ (bubble-sort [1 2 3]) [3 2 1]
112
+ (load "bubble_version_2.shen") loaded
113
+ (bubble-sort [1 2 3]) [3 2 1]
114
+ \* (load "newton_version_1.shen") loaded
115
+ (newtons-method 4) 2
116
+ (load "newton_version_2.shen") loaded
117
+ (newtons-method 4) 2 *\
118
+ (load "spreadsheet.shen") loaded
119
+ (assess-spreadsheet [[jim [wages (/. Spreadsheet (get' frank wages Spreadsheet))]
120
+ [tax (/. Spreadsheet (* (get' frank tax Spreadsheet) .8))]]
121
+ [frank [wages 20000]
122
+ [tax (/. Spreadsheet (* .25 (get' frank wages Spreadsheet)))]]])
123
+
124
+ [[jim [wages 20000] [tax 4000.0]] [frank [wages 20000] [tax 5000.0]]] )
125
+
126
+ (report "FPQi chapter 3"
127
+
128
+ (load "prime.shen") loaded
129
+ (prime? 1000003) true
130
+ (load "mutual.shen") loaded
131
+ (even? 56) true
132
+ (odd? 77) true
133
+ (load "change.shen") loaded
134
+ (count-change 100) 4563
135
+ )
136
+
137
+ (report "FPQi chapter 6"
138
+ (load "semantic_net.shen") loaded
139
+ (clear Mark_Tarver) []
140
+ (clear man) []
141
+ (assert [Mark_Tarver is_a man]) [man]
142
+ (assert [man type_of human]) [human]
143
+ (query [is Mark_Tarver human]) yes)
144
+
145
+ (report "FPQi chapter 7"
146
+
147
+ (load "proplog_version_1.shen") loaded
148
+ (backchain q [[q <= p] [q <= r] [r <=]]) proved
149
+ (backchain q [[q <= p] [q <= r]]) (fail)
150
+ (load "proplog_version_2.shen") loaded
151
+ (backchain q [[q <= p] [q <= r] r]) true
152
+ (backchain q [[q <= p] [q <= r]]) false
153
+ )
154
+
155
+ (report "FPQi chapter 8"
156
+
157
+ (load "metaprog.shen") loaded
158
+ (generate_parser [sent --> np vp np --> name np --> det n
159
+ name --> "John" name --> "Bill"
160
+ name --> "Tom" det --> "the" det --> "a"
161
+ det --> "that" det --> "this"
162
+ n --> "girl" n --> "ball"
163
+ vp --> vtrans np vp --> vintrans
164
+ vtrans --> "kicks" vtrans --> "likes"
165
+ vintrans --> "jumps" vintrans --> "flies"]) [sent np name det n vp vtrans vintrans]
166
+
167
+ )
168
+
169
+ (report "chapter 11"
170
+ (load "binary.shen") loaded
171
+ (complement [1 0]) [0 1]
172
+ (load "streams.shen") loaded
173
+ (fst (delay (@p 0 (+ 1) (/. X false)))) 1)
174
+
175
+ (report "strings"
176
+ (load "strings.shen") loaded
177
+ (subst-string "a" "b" "cba") "caa"
178
+ (strlen "123") 3
179
+ (trim-string-left [" "] " hi ") "hi "
180
+ (trim-string-right [" "] " hi ") " hi"
181
+ (trim-string [" "] " hi ") "hi"
182
+ (reverse-string "abc") "cba"
183
+ (alldigits? "123") true)
184
+
185
+ (report "calculator.shen - chapter 11"
186
+ (load "calculator.shen") loaded
187
+ (do-calculation [[num 12] + [[num 7] * [num 4]]]) 40 )
188
+
189
+ (report "structures 1 - chapter 12"
190
+ (load "structures-untyped.shen") loaded
191
+ (defstruct ship [length name]) ship
192
+ (make-ship 200 "Mary Rose") [[structure | ship] [length | 200] [name | "Mary Rose"]]
193
+ (ship-length (make-ship 200 "Mary Rose")) 200
194
+ (ship-name (make-ship 200 "Mary Rose")) "Mary Rose" )
195
+
196
+ (report "structures 2 - chapter 12"
197
+ (load "structures-typed.shen") loaded
198
+ (defstruct ship [(@p length number) (@p name string)]) ship
199
+ (make-ship 200 "Mary Rose") [[structure | ship] [length | 200] [name | "Mary Rose"]]
200
+ (ship-length (make-ship 200 "Mary Rose")) 200
201
+ (ship-name (make-ship 200 "Mary Rose")) "Mary Rose")
202
+
203
+ (report "classes 1 - chapter 12"
204
+ (load "classes-untyped.shen") loaded
205
+ (defclass ship [length name]) ship
206
+ (set s (make-instance ship)) [[class | ship] [length | fail] [name | fail]]
207
+ (has-value? length (value s)) false
208
+ (set s (change-value (value s) length 100)) [[class | ship] [length | 100] [name | fail]]
209
+ (get-value length (value s)) 100)
210
+
211
+ (report "classes 2 - chapter 12"
212
+ (load "classes-typed.shen") loaded
213
+ (defclass ship [(@p length number) (@p name string)]) ship
214
+ (has-value? length (make-instance ship)) false
215
+ (change-value (make-instance ship) length 100) [[class | ship] [length | 100] [name | fail]]
216
+ (get-value length (change-value (make-instance ship) length 100)) 100)
217
+
218
+ (report "abstract datatypes - chapter 12"
219
+ (load "stack.shen") loaded
220
+ (top (push 0 (empty-stack _))) 0
221
+ )
222
+
223
+ (report "yacc"
224
+ (load "yacc.shen") loaded
225
+ (compile <sent> [the cat likes the dog]) [the cat likes the dog]
226
+ (compile <sent> [the cat likes the canary]) (fail)
227
+ (compile <asbscs> [a a a b b c]) [a a a b b c]
228
+ (compile <find-digit> [a v f g 6 y u]) [6]
229
+ (compile <vp> [chases the cat]) [chases the cat]
230
+ (compile <des> [[d] [e e]]) [d e e]
231
+ (compile <sent'> [the cat likes the dog]) [is it true that your father likes the dog ?]
232
+ (compile <as> [a a a]) [a a a]
233
+ (compile <find-digit'> [a v f g 6 y u]) [6 y u]
234
+ (compile <asbs'cs> [a v f g 6 y u]) (fail)
235
+ (compile <find-digit''> [a v f g 6 y u]) 6
236
+ (compile <anbncn> [a a a b b b c c c]) [a a a b b b c c c] )
237
+
238
+ (preclude-all-but [])
239
+ (tc +)
240
+
241
+ (report "N Queens"
242
+ (preclude-all-but []) []
243
+ (tc +) true
244
+ (load "n_queens.shen") loaded
245
+ (n-queens 5) [[4 2 5 3 1] [3 5 2 4 1] [5 3 1 4 2] [4 1 3 5 2] [5 2 4 1 3] [1 4 2 5 3]
246
+ [2 5 3 1 4] [1 3 5 2 4] [3 1 4 2 5] [2 4 1 3 5]]
247
+ (tc -) false)
248
+
249
+ (report "search"
250
+ (tc +) true
251
+ (load "search.shen") loaded
252
+ (tc -) false)
253
+
254
+ (report "whist - chapter 11"
255
+ (tc +) true
256
+ (load "whist.shen") loaded
257
+ (tc -) false)
258
+
259
+ (report "Qi interpreter - chapter 13"
260
+ (tc +) true
261
+ (load "interpreter.shen") loaded
262
+ (tc -) false)
263
+
264
+ (report "proof assistant - chapter 15"
265
+ (tc +) true
266
+ (load "proof_assistant.shen") loaded
267
+ (tc -) false)
268
+
269
+ (report "quantifier machine"
270
+ (tc +) true
271
+ (load "qmachine.shen") loaded
272
+ \* (filter [1 (+ 1) (= 100)] (/. X (integer? (sqrt X)))) [1 4 9 16 25 36 49 64 81] *\
273
+ (exists [1 (+ 1) (= 100)] (> 50)) true
274
+ (tc -) false)
275
+
276
+ (report "depth first search"
277
+ (tc +) true
278
+ (load "depth_.shen") loaded
279
+ (depth' 4 (/. X [(+ X 3) (+ X 4) (+ X 5)]) (/. X (= X 27)) (/. X (> X 27))) [4 7 10 13 16 19 22 27]
280
+ (depth' 4 (/. X [(+ X 3)]) (/. X (= X 27)) (/. X (> X 27))) []
281
+ (tc -) false)
282
+
283
+ \* (report "red/black trees"
284
+ (tc +) true
285
+ (load "red-black.shen") loaded) *\
286
+
287
+ (report "Lisp type checker"
288
+
289
+ (load "TinyTypes.shen") loaded
290
+ (tc +) true
291
+ (load "TinyLispFunctions.txt") loaded
292
+ (tc -) false )
293
+
294
+ (reset)
@@ -0,0 +1,11 @@
1
+ (if-without-checking "switch on the typechecker first!~%")
2
+
3
+ (datatype fruit
4
+
5
+ if (element? Fruit [cherry pear orange pineapple lemon])
6
+ _____________
7
+ Fruit : fruit;)
8
+
9
+
10
+
11
+
@@ -0,0 +1,240 @@
1
+ (synonyms
2
+ card (rank * suit)
3
+ cscore number
4
+ pscore number )
5
+
6
+ (datatype rank
7
+
8
+ if (element? Rank [2 3 4 5 6 7 8 9 10 11 12 13 14])
9
+ ___________________________________________________
10
+ Rank : rank;
11
+
12
+ Rank : rank;
13
+ ___________
14
+ Rank : number;)
15
+
16
+ (datatype suit
17
+
18
+ if (element? Suit [c d h s])
19
+ ____________________________
20
+ Suit : suit;)
21
+
22
+ (datatype lead
23
+
24
+ if (element? L [player computer])
25
+ _________________________________
26
+ L : lead;)
27
+
28
+ (define whist
29
+ {lead --> string}
30
+ Lead -> (whist-loop (deal-whist 13 (deck _) (@p [] [])) 0 0 Lead))
31
+
32
+ (define deck
33
+ {A --> (list card)}
34
+ _ -> (cartprod [2 3 4 5 6 7 8 9 10 11 12 13 14] [c d h s]))
35
+
36
+ (define cartprod
37
+ {[A] --> [B] --> [(A * B)]}
38
+ [] _ -> []
39
+ [X | Y] Z -> (append (map (/. W (@p X W)) Z) (cartprod Y Z)))
40
+
41
+ (define deal-whist
42
+ {number --> (list card) --> ((list card) * (list card)) --> ((list card) * (list card))}
43
+ 0 _ (@p Computer Player) -> (@p Computer Player)
44
+ N Deck (@p Computer Player)
45
+ -> (let CCard (deal-card Deck)
46
+ Deck-1 (remove CCard Deck)
47
+ PCard (deal-card Deck-1)
48
+ Deck-2 (remove PCard Deck-1)
49
+ (deal-whist (- N 1) Deck-2 (@p [CCard | Computer] [PCard | Player]))))
50
+
51
+ (define deal-card
52
+ {(list card) --> card}
53
+ Cards -> (nth (+ (random (length Cards)) 1) Cards))
54
+
55
+ (define random
56
+ {A --> A}
57
+ X -> X)
58
+
59
+ (define whist-loop
60
+ {((list card) * (list card)) --> cscore --> pscore --> lead --> string}
61
+ Hands Cscore Pscore _
62
+ -> (if (> Cscore Pscore)
63
+ (output "~%Computer tricks: ~A, Player tricks: ~A; ~%Computer wins!~%"
64
+ Cscore Pscore)
65
+ (output "~%Computer tricks: ~A, Player tricks: ~A; ~%You win!~%"
66
+ Cscore Pscore))
67
+ where (game-over? Hands)
68
+ (@p Computer Player) Cscore Pscore computer
69
+ -> (let Ccard (computer-shows (play-computer-lead Computer))
70
+ Pcard (determine-legal (play-player Player) Ccard Player)
71
+ Winner (return-winner (determine-winner Ccard Pcard computer))
72
+ Computer-1 (remove Ccard Computer)
73
+ Player-1 (remove Pcard Player)
74
+ (if (= Winner computer)
75
+ (whist-loop (@p Computer-1 Player-1)
76
+ (+ 1 Cscore)
77
+ Pscore
78
+ computer)
79
+ (whist-loop (@p Computer-1 Player-1)
80
+ Cscore
81
+ (+ Pscore 1)
82
+ player)))
83
+ (@p Computer Player) Cscore Pscore player
84
+ -> (let Pcard (play-player Player)
85
+ Ccard (computer-shows (play-computer-follow Computer Pcard))
86
+ Winner (return-winner (determine-winner Ccard Pcard player))
87
+ Computer-1 (remove Ccard Computer)
88
+ Player-1 (remove Pcard Player)
89
+ (if (= Winner computer)
90
+ (whist-loop (@p Computer-1 Player-1)
91
+ (+ 1 Cscore)
92
+ Pscore
93
+ computer)
94
+ (whist-loop (@p Computer-1 Player-1)
95
+ Cscore
96
+ (+ Pscore 1)
97
+ player))))
98
+
99
+ (define determine-legal
100
+ {card --> card --> (list card) --> card}
101
+ Pcard Ccard Player -> Pcard where (legal? Pcard Ccard Player)
102
+ _ Ccard Player -> (do (output "You must follow suit!" [])
103
+ (determine-legal (play-player Player)
104
+ Ccard
105
+ Player)))
106
+
107
+ (define legal?
108
+ {card --> card --> (list card) --> boolean}
109
+ (@p _ Suit) (@p _ Suit) _ -> true
110
+ _ (@p _ Suit) Player -> (void-of-suit? Suit Player))
111
+
112
+ (define void-of-suit?
113
+ {suit --> (list card) --> boolean}
114
+ Suit Player -> (empty? (same-suit Player Suit)))
115
+
116
+ (define same-suit
117
+ {(list card) --> suit --> (list card)}
118
+ [] _ -> []
119
+ [(@p Rank Suit) | Cards] Suit -> [(@p Rank Suit) | (same-suit Cards Suit)]
120
+ [_ | Cards] Suit -> (same-suit Cards Suit))
121
+
122
+ (define determine-winner
123
+ {card --> card --> lead --> lead}
124
+ (@p Rank1 Suit) (@p Rank2 Suit) _ -> (if (> Rank1 Rank2) computer player)
125
+ _ _ Lead -> Lead)
126
+
127
+ (define return-winner
128
+ {lead --> lead}
129
+ computer -> (do (output "~%Computer wins the trick.~%____________________________________________~%" [])
130
+ computer)
131
+ player -> (do (output "~%Player wins the trick.~%____________________________________________~%" [])
132
+ player))
133
+
134
+ (define game-over?
135
+ {((list card) * (list card)) --> boolean}
136
+ (@p [] []) -> true
137
+ _ -> false)
138
+
139
+ (define play-computer-lead
140
+ {(list card) --> card}
141
+ Cards -> (select-highest Cards))
142
+
143
+ (define computer-shows
144
+ {card --> card}
145
+ (@p Rank Suit) -> (do (output "~%Computer plays the ~A of ~A~%"
146
+ (map-rank Rank) (map-suit Suit))
147
+ (@p Rank Suit)))
148
+
149
+ (define map-rank
150
+ {rank --> string}
151
+ 14 -> "ace"
152
+ 13 -> "king"
153
+ 12 -> "queen"
154
+ 11 -> "jack"
155
+ N -> (make-string "~A" N))
156
+
157
+ (define map-suit
158
+ {suit --> string}
159
+ c -> "c#5;"
160
+ d -> "c#4;"
161
+ h -> "c#3;"
162
+ s -> "c#6;")
163
+
164
+ (define select-highest
165
+ {(list card) --> card}
166
+ [Card | Cards] -> (select-highest-help Card Cards))
167
+
168
+ (define select-highest-help
169
+ {card --> (list card) --> card}
170
+ Card [] -> Card
171
+ Card1 [Card2 | Cards]
172
+ -> (select-highest-help Card2 Cards) where (higher? Card2 Card1)
173
+ Card [_ | Cards] -> (select-highest-help Card Cards))
174
+
175
+ (define higher?
176
+ {card --> card --> boolean}
177
+ (@p Rank1 _) (@p Rank2 _) -> (> Rank1 Rank2))
178
+
179
+ (define play-computer-follow
180
+ {(list card) --> card --> card}
181
+ Cards (@p Rank Suit)
182
+ -> (let FollowSuit (sort lower? (same-suit Cards Suit))
183
+ (if (empty? FollowSuit)
184
+ (select-lowest Cards)
185
+ (let Ccard (select-higher (@p Rank Suit) FollowSuit)
186
+ (if (= (determine-winner Ccard (@p Rank Suit) player) computer)
187
+ Ccard
188
+ (head FollowSuit))))))
189
+
190
+ (define sort
191
+ {(A --> A --> boolean) --> (list A) --> (list A)}
192
+ R X -> (fix (/. Y (sort-help R Y)) X))
193
+
194
+ (define sort-help
195
+ {(A --> A --> boolean) --> (list A) --> (list A)}
196
+ _ [] -> []
197
+ _ [X] -> [X]
198
+ R [X Y | Z] -> [Y | (sort-help R [X | Z])] where (R Y X)
199
+ R [X | Y] -> [X | (sort-help R Y)])
200
+
201
+ (define select-higher
202
+ {card --> (list card) --> card}
203
+ _ [Card] -> Card
204
+ Card1 [Card2 | _] -> Card2 where (higher? Card2 Card1)
205
+ Card [_ | Cards] -> (select-higher Card Cards))
206
+
207
+ (define select-lowest
208
+ {(list card) --> card}
209
+ [Card | Cards] -> (select-lowest-help Card Cards))
210
+
211
+ (define select-lowest-help
212
+ {card --> (list card) --> card}
213
+ Card [] -> Card
214
+ Card1 [Card2 | Cards]
215
+ -> (select-lowest-help Card2 Cards) where (lower? Card2 Card1)
216
+ Card [_ | Cards] -> (select-lowest-help Card Cards))
217
+
218
+ (define lower?
219
+ {card --> card --> boolean}
220
+ (@p Rank1 _) (@p Rank2 _) -> (< Rank1 Rank2))
221
+
222
+ (define play-player
223
+ {(list card) --> card}
224
+ Cards -> (do (output "~%Your hand is ~%~%")
225
+ (show-cards 1 Cards)
226
+ (let N (input+ : number)
227
+ (if (in-range? N Cards)
228
+ (nth N Cards)
229
+ (play-player Cards)))))
230
+
231
+ (define show-cards
232
+ {number --> (list card) --> string}
233
+ _ [] -> (output "~%~%Choose a Card: ")
234
+ N [(@p Rank Suit) | Cards]
235
+ -> (do (output "~%~A. ~A of ~A" N (map-rank Rank) (map-suit Suit))
236
+ (show-cards (+ N 1) Cards)))
237
+
238
+ (define in-range?
239
+ {number --> (list card) --> boolean}
240
+ N Cards -> (and (integer? N) (and (> N 0) (<= N (length Cards)))))