aa
TestHM7.java
Go to the documentation of this file.
1 package com.cliffc.aa.HM;
2 
3 import org.junit.Before;
4 import org.junit.Test;
5 
6 import static com.cliffc.aa.HM.HM7.T2;
7 import static org.junit.Assert.assertEquals;
8 
9 public class TestHM7 {
10 
11  @Before public void reset() { HM7.reset(); }
12 
13  @Test(expected = RuntimeException.class)
14  public void test00() {
15  HM7.hm("fred");
16  }
17 
18  @Test
19  public void test01() {
20  T2 t = HM7.hm("3");
21  assertEquals("3",t.p());
22  }
23 
24  @Test
25  public void test02() {
26  T2 t = HM7.hm("(pair1 3)");
27  assertEquals("{ A -> (pair 3 A) }",t.p());
28  }
29 
30  @Test
31  public void test03() {
32  T2 t = HM7.hm("{ z -> (pair (z 3) (z \"abc\")) }");
33  assertEquals("{ { all -> A } -> (pair A A) }",t.p());
34  }
35 
36  @Test
37  public void test04() {
38  T2 t = HM7.hm("fact = { n -> (if (?0 n) 1 (* n (fact (dec n))))}; fact");
39  assertEquals("{ int64 -> int64 }",t.p());
40  }
41 
42  @Test
43  public void test05() {
44  // Because {y->y} is passed in, all 'y' types must agree.
45  // This unifies 3 and "abc" which results in 'all'
46  T2 t1 = HM7.hm("({ x -> (pair (x 3) (x \"abc\")) } {y->y})");
47  assertEquals("(pair all all)",t1.p());
48  }
49 
50  @Test//(expected = RuntimeException.class) No longer throws, but returns a recursive type
51  public void test06() {
52  // recursive unification
53  T2 t1 = HM7.hm("{ f -> (f f) }");
54  assertEquals("{ A:{ $A -> B } -> B }",t1.p());
55  // We can argue the pretty-print should print:
56  // "A:{ $A -> B }"
57  }
58 
59  @Test
60  public void test07() {
61  T2 t1 = HM7.hm("g = {f -> 5}; (g g)");
62  assertEquals("5",t1.p());
63  }
64 
65  @Test
66  public void test08() {
67  // example that demonstrates generic and non-generic variables:
68  T2 t1 = HM7.hm("{ g -> f = { x -> g }; (pair (f 3) (f \"abc\"))}");
69  assertEquals("{ A -> (pair A A) }",t1.p());
70  }
71 
72  @Test
73  public void test09() {
74  T2 t1 = HM7.hm("{ f g -> (f g)}");
75  assertEquals("{ { A -> B } A -> B }",t1.p());
76  }
77 
78  @Test
79  public void test10() {
80  // Function composition
81  T2 t1 = HM7.hm("{ f g -> { arg -> (g (f arg))} }");
82  assertEquals("{ { A -> B } { B -> C } -> { A -> C } }",t1.p());
83  }
84 
85  @Test
86  public void test11() {
87  // Stacked functions ignoring all function arguments
88  T2 t1 = HM7.hm("map = { fun -> { x -> 2 } }; ((map 3) 5)");
89  assertEquals("2",t1.p());
90  }
91 
92  @Test
93  public void test12() {
94  // map takes a function and an element (collection?) and applies it (applies to collection?)
95  T2 t1 = HM7.hm("map = { fun -> { x -> (fun x)}}; { p -> 5 }");
96  assertEquals("{ A -> 5 }",t1.p());
97  }
98 
99  @Test
100  public void test13() {
101  // Looking at when tvars are duplicated ("fresh" copies made).
102  // This is the "map" problem with a scalar instead of a collection.
103  // Takes a '{a->b}' and a 'a' for a couple of different prims.
104  T2 t1 = HM7.hm("map = { fun -> { x -> (fun x)}};"+
105  "(pair ((map str) 5) ((map factor) 2.3))");
106  assertEquals("(pair str (divmod flt64 flt64))",t1.p());
107  }
108 
109  @Test
110  public void test14() {
111  // map takes a function and an element (collection?) and applies it (applies to collection?)
112  T2 t1 = HM7.hm("map = { fun x -> (fun x)}; (map {a->3} 5)");
113  assertEquals("3",t1.p());
114  }
115 
116  @Test
117  public void test15() {
118  // map takes a function and an element (collection?) and applies it (applies to collection?)
119  T2 t1 = HM7.hm("map = { fun x -> (fun x)}; (map { a-> (pair a a)} 5)");
120  assertEquals("(pair 5 5)",t1.p());
121  }
122 
123  @Test
124  public void test16() {
125  T2 t1 = HM7.hm("fcn = { p -> { a -> (pair a a) }};"+
126  "map = { fun x -> (fun x)};"+
127  "{ q -> (map (fcn q) 5)}");
128  assertEquals("{ A -> (pair 5 5) }",t1.p());
129  }
130 
131  @Test(expected = RuntimeException.class)
132  public void test17() {
133  // Checking behavior when using "if" to merge two functions with
134  // sufficiently different signatures, then attempting to pass them to a map
135  // & calling internally.
136  // fcn takes a predicate 'p' and returns one of two fcns.
137  // let fcn = { p -> (if p {a -> pair[a,a ]}
138  // {b -> pair[b,pair[3,b]]}) } in
139  // map takes a function and an element (collection?) and applies it (applies to collection?)
140  // let map = { fun x -> (fun x) }
141  // in { q -> ((map (fcn q)) 5) }
142  // Should return { q -> q ? [5,5] : [5,[3,5]] }
143  // Ultimately, unifies "a" with "pair[3,a]" which throws recursive unification.
144  T2 t1 = HM7.hm("fcn = {p -> (if p {a -> (pair a a)} {b -> (pair b (pair 3 b))})};"+
145  "map = { fun x -> (fun x)};"+
146  "{ q -> (map (fcn q) 5)}");
147  assertEquals("TBD",t1.p());
148  }
149 
150  @Test
151  public void test18() {
152  T2 t1 = HM7.hm("cons ={x y-> {cadr -> (cadr x y)}};"+
153  "cdr ={mycons -> (mycons { p q -> q})};"+
154  "(cdr (cons 2 3))");
155  assertEquals("3",t1.p());
156  }
157 
158  // Take 2nd element of pair, and applies a function.
159  // let map = fn parg fun => (fun (cdr parg))
160  // Some pairs:
161  // let intz = (pair2 false 3)
162  // let strz = (pair2 false "abc")
163  // in pair(map(str,intz),map(isempty,strz))
164  // Expects: ("2",false)
165  @Test
166  public void test19() {
167  T2 t1 = HM7.hm("cons ={x y-> {cadr -> (cadr x y)}};"+
168  "cdr ={mycons -> (mycons { p q -> q})};"+
169  "map ={fun parg -> (fun (cdr parg))};"+
170  "(pair (map str (cons 0 5)) (map isempty (cons 0 \"abc\")))"
171  );
172  assertEquals("(pair str int1)",t1.p());
173  }
174 
175  // Obscure factorial-like
176  @Test
177  public void test20() {
178  T2 t1 = HM7.hm("f0 = { f x -> (if (?0 x) 1 (f (f0 f (dec x)) 2))}; (f0 * 99)");
179  assertEquals("int64",t1.p());
180  }
181 
182  // Obscure factorial-like
183  @Test
184  public void test21() {
185  // let f0 = fn f x => (if (?0 x) 1 (* (f0 f (dec x)) 2) ) in f0 f0 99
186  // let f0 = fn f x => (if (?0 x) 1 (f (f0 f (dec x)) 2) ) in f0 * 99
187  T2 t1 = HM7.hm("f0 = { f x -> (if (?0 x) 1 (* (f0 f (dec x)) 2))}; (f0 f0 99)");
188  assertEquals("int64",t1.p());
189  }
190 
191  // Mutual recursion
192  @Test
193  public void test22() {
194  T2 t1 = HM7.hm("is_even = "+
195  " is_odd = { n -> (if (?0 n) 0 (is_even (dec n)))}; "+
196  " { n -> (if (?0 n) 1 (is_odd (dec n)))};"+
197  "(is_even 3)"
198  );
199  assertEquals("int1",t1.p());
200  }
201 
202  // Toss a function into a pair & pull it back out
203  @Test
204  public void test23() {
205  T2 t1 = HM7.hm("{ g -> fgz = "+
206  " cons = {x y -> {cadr -> (cadr x y)}};"+
207  " cdr = {mycons -> (mycons { p q -> q})};"+
208  " (cdr (cons 2 { z -> (g z) }));"+
209  " (pair (fgz 3) (fgz 5))"+
210  "}"
211  );
212  assertEquals("{ { nint8 -> A } -> (pair A A) }",t1.p());
213  }
214 
215  // Basic structure test
216  @Test
217  public void test24() {
218  T2 t = HM7.hm("@{x=2, y=3}");
219  assertEquals("@{ x = 2, y = 3}",t.p());
220  }
221 
222  // Basic field test
223  @Test
224  public void test25() {
225  T2 t = HM7.hm(".x @{x =2, y =3}");
226  assertEquals("2",t.p());
227  }
228 
229  @Test
230  public void test26() {
231  T2 t = HM7.hm("{ g -> @{x=g, y=g}}");
232  assertEquals("{ A -> @{ x = A, y = A} }",t.p());
233  }
234 
235  @Test
236  public void test27() {
237  // Load common field 'x', ignoring mismatched fields y and z
238  T2 t = HM7.hm("{ pred -> .x (if pred @{x=2,y=3} @{x=3,z= \"abc\"}) }");
239  assertEquals("{ A -> nint8 }",t.p());
240  }
241 
242  @Test
243  public void test28() {
244  // Load some fields from an unknown struct: area of a square.
245  // Since no nil-check, correct types as needing a not-nil input.
246  T2 t = HM7.hm("{ sq -> (* .x sq .y sq) }");
247  assertEquals("{ @{ y = int64, x = int64} -> int64 }",t.p());
248  }
249 
250  @Test
251  public void test29() {
252  // Recursive linked-list discovery, with no end clause
253  T2 t = HM7.hm("map = { fcn lst -> @{ n1 = (map fcn .n0 lst), v1 = (fcn .v0 lst) } }; map");
254  assertEquals("{ { A -> B } C:@{ v0 = A, n0 = $C} -> D:@{ n1 = $D, v1 = B} }",t.p());
255  }
256 
257  @Test
258  public void test30() {
259  // Recursive linked-list discovery, with nil
260  T2 t = HM7.hm("map = { fcn lst -> (if lst @{ n1=(map fcn .n0 lst), v1=(fcn .v0 lst) } nil) }; map");
261  assertEquals("{ { A -> B } C:@{ v0 = A, n0 = $C}? -> D:@{ n1 = $D, v1 = B}? }",t.p());
262  }
263 
264  // try the worse-case expo blow-up test case from SO
265  @Test
266  public void test31() {
267  // Recursive linked-list discovery, with nil
268  T2 t = HM7.hm("p0 = { x y z -> (triple x y z) };"+
269  "p1 = (triple p0 p0 p0);"+
270  "p2 = (triple p1 p1 p1);"+
271  "p3 = (triple p2 p2 p2);"+
272  "p3");
273  assertEquals("(triple (triple (triple { A B C -> (triple A B C) } { D E F -> (triple D E F) } { G H I -> (triple G H I) }) (triple { J K L -> (triple J K L) } { M N O -> (triple M N O) } { P Q R -> (triple P Q R) }) (triple { S T U -> (triple S T U) } { V21 V22 V23 -> (triple V21 V22 V23) } { V24 V25 V26 -> (triple V24 V25 V26) })) (triple (triple { V27 V28 V29 -> (triple V27 V28 V29) } { V30 V31 V32 -> (triple V30 V31 V32) } { V33 V34 V35 -> (triple V33 V34 V35) }) (triple { V36 V37 V38 -> (triple V36 V37 V38) } { V39 V40 V41 -> (triple V39 V40 V41) } { V42 V43 V44 -> (triple V42 V43 V44) }) (triple { V45 V46 V47 -> (triple V45 V46 V47) } { V48 V49 V50 -> (triple V48 V49 V50) } { V51 V52 V53 -> (triple V51 V52 V53) })) (triple (triple { V54 V55 V56 -> (triple V54 V55 V56) } { V57 V58 V59 -> (triple V57 V58 V59) } { V60 V61 V62 -> (triple V60 V61 V62) }) (triple { V63 V64 V65 -> (triple V63 V64 V65) } { V66 V67 V68 -> (triple V66 V67 V68) } { V69 V70 V71 -> (triple V69 V70 V71) }) (triple { V72 V73 V74 -> (triple V72 V73 V74) } { V75 V76 V77 -> (triple V75 V76 V77) } { V78 V79 V80 -> (triple V78 V79 V80) })))",t.p());
274  }
275 
276  // Need to see if a map call, inlined a few times, 'rolls up'. Sometimes
277  // rolls up, sometimes not; depends on worklist visitation order.
278  @Test
279  public void test32() {
280  // Recursive linked-list discovery, with nil. Unrolled once.
281  T2 t = HM7.hm("map = { lst -> (if lst @{ n1= arg= .n0 lst; (if arg @{ n1=(map .n0 arg), v1=(str .v0 arg)} nil), v1=(str .v0 lst) } nil) }; map");
282  assertEquals("{ A:@{ v0 = int64, n0 = @{ n0 = $A, v0 = int64}?}? -> B:@{ n1 = @{ n1 = $B, v1 = str}?, v1 = str}? }",t.p());
283  }
284 }
com.cliffc.aa.HM.TestHM7.test25
void test25()
Definition: TestHM7.java:224
com.cliffc.aa.HM.TestHM7.test06
void test06()
Definition: TestHM7.java:51
com.cliffc.aa.HM.TestHM7.test29
void test29()
Definition: TestHM7.java:251
com.cliffc.aa.HM.HM7
Definition: HM7.java:23
com.cliffc.aa.HM.TestHM7.test02
void test02()
Definition: TestHM7.java:25
com.cliffc.aa.HM.TestHM7.test10
void test10()
Definition: TestHM7.java:79
com.cliffc.aa.HM.TestHM7
Definition: TestHM7.java:9
com.cliffc.aa.HM.TestHM7.test27
void test27()
Definition: TestHM7.java:236
com.cliffc.aa.HM.HM7.T2.p
String p()
Definition: HM7.java:1082
com.cliffc.aa.HM.TestHM7.test12
void test12()
Definition: TestHM7.java:93
com.cliffc
com.cliffc.aa.HM.TestHM7.test32
void test32()
Definition: TestHM7.java:279
com.cliffc.aa.HM.TestHM7.test04
void test04()
Definition: TestHM7.java:37
com.cliffc.aa.HM.TestHM7.test17
void test17()
Definition: TestHM7.java:132
com.cliffc.aa.HM.TestHM7.reset
void reset()
Definition: TestHM7.java:11
com.cliffc.aa.HM.TestHM7.test19
void test19()
Definition: TestHM7.java:166
com.cliffc.aa.HM.TestHM7.test11
void test11()
Definition: TestHM7.java:86
com.cliffc.aa.HM.TestHM7.test00
void test00()
Definition: TestHM7.java:14
com.cliffc.aa.HM.TestHM7.test13
void test13()
Definition: TestHM7.java:100
com.cliffc.aa.HM.TestHM7.test20
void test20()
Definition: TestHM7.java:177
com.cliffc.aa.HM.TestHM7.test26
void test26()
Definition: TestHM7.java:230
com.cliffc.aa.HM.TestHM7.test30
void test30()
Definition: TestHM7.java:258
com.cliffc.aa.HM.TestHM7.test28
void test28()
Definition: TestHM7.java:243
com.cliffc.aa.HM.HM7.T2
Definition: HM7.java:621
com.cliffc.aa.HM.TestHM7.test05
void test05()
Definition: TestHM7.java:43
com.cliffc.aa.HM.TestHM7.test09
void test09()
Definition: TestHM7.java:73
com.cliffc.aa.HM.TestHM7.test08
void test08()
Definition: TestHM7.java:66
com.cliffc.aa.HM.TestHM7.test07
void test07()
Definition: TestHM7.java:60
com.cliffc.aa.HM.TestHM7.test01
void test01()
Definition: TestHM7.java:19
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.HM.TestHM7.test31
void test31()
Definition: TestHM7.java:266
com.cliffc.aa.HM.HM7.reset
static void reset()
Definition: HM7.java:89
com.cliffc.aa.HM
Definition: HM.java:1
com.cliffc.aa.HM.TestHM7.test24
void test24()
Definition: TestHM7.java:217
com.cliffc.aa.HM.TestHM7.test15
void test15()
Definition: TestHM7.java:117
com.cliffc.aa.HM.HM7.hm
static T2 hm(String sprog)
Definition: HM7.java:27
com.cliffc.aa.HM.TestHM7.test22
void test22()
Definition: TestHM7.java:193
com.cliffc.aa.HM.TestHM7.test18
void test18()
Definition: TestHM7.java:151
com
com.cliffc.aa.HM.TestHM7.test21
void test21()
Definition: TestHM7.java:184
com.cliffc.aa.HM.TestHM7.test03
void test03()
Definition: TestHM7.java:31
com.cliffc.aa.HM.TestHM7.test16
void test16()
Definition: TestHM7.java:124
com.cliffc.aa.HM.TestHM7.test23
void test23()
Definition: TestHM7.java:204
com.cliffc.aa.HM.TestHM7.test14
void test14()
Definition: TestHM7.java:110