shen-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)))))