aa
TestHM3.java
Go to the documentation of this file.
1 package com.cliffc.aa.HM;
2 
3 import com.cliffc.aa.type.*;
4 import org.junit.Before;
5 import org.junit.Test;
6 
7 import static com.cliffc.aa.HM.HM3.*;
8 import static org.junit.Assert.assertEquals;
9 
10 public class TestHM3 {
11 
12  @Before public void reset() { HM3.reset(); }
13 
14  @Test(expected = RuntimeException.class)
15  public void test00() {
16  Syntax syn = new Ident("fred");
17  HM3.hm(syn);
18  }
19 
20  @Test
21  public void test01() {
22  Syntax syn = new Con(TypeInt.con(3));
23  HMVar t = (HMVar)HM3.hm(syn);
24  assertEquals(TypeInt.con(3),t.type());
25  }
26 
27  @Test
28  public void test02() {
29  Syntax syn = new Apply(new Ident("pair"),new Con(TypeInt.con(3)));
30  HMType t = HM3.hm(syn);
31  assertEquals("{ v25 -> pair(v21:3,v25$) }",t.str());
32  }
33 
34  @Test
35  public void test03() {
36  // let fact = {n -> ( if/else (==0 n) 1 ( * n (fact (dec n))))} in fact;
37  // let fact = {n -> (((if/else (==0 n)) 1) ((* n) (fact (dec n))))} in fact;
38  Syntax fact =
39  new Let("fact",
40  new Lambda("n",
41  new Apply(new Apply( new Apply(new Ident("if/else"),
42  new Apply(new Ident("==0"),new Ident("n"))),
43  new Con(TypeInt.con(1))),
44  new Apply(new Apply(new Ident("*"), new Ident("n")),
45  new Apply(new Ident("fact"),
46  new Apply(new Ident("dec"),new Ident("n")))))),
47  new Ident("fact"));
48  HMType t1 = HM3.hm(fact);
49  assertEquals("{ v31:int64 -> v31$ }",t1.str());
50  }
51 
52  @Test
53  public void test04() {
54  // { x -> (pair (x 3) (x "abc")) }
55  Syntax x =
56  new Lambda("x",
57  new Apply(new Apply(new Ident("pair"),
58  new Apply(new Ident("x"), new Con(TypeInt.con(3)))),
59  new Apply(new Ident("x"), new Con(TypeStr.ABC))));
60  HMType t1 = HM3.hm(x);
61  assertEquals("{ { v22:all -> v23 } -> pair(v23$,v23$) }",t1.str());
62  }
63 
64  @Test
65  public void test05() {
66  // ({ x -> (pair (x 3) (x "abc")) } {y->y})
67  Syntax x =
68  new Apply(new Lambda("x",
69  new Apply(new Apply(new Ident("pair"),
70  new Apply(new Ident("x"), new Con(TypeInt.con(3)))),
71  new Apply(new Ident("x"), new Con(TypeStr.ABC)))),
72  new Lambda("y", new Ident("y")));
73 
74  HMType t1 = HM3.hm(x);
75  assertEquals("pair(v22:all,v22$)",t1.str());
76  }
77 
78 
79  @Test
80  public void test05a() {
81  // let x = {y->y} in (pair (x 3) (x "abc"))
82  Syntax x =
83  new Let("x",
84  new Lambda("y", new Ident("y")),
85  new Apply(new Apply(new Ident("pair"),
86  new Apply(new Ident("x"), new Con(TypeInt.con(3)))),
87  new Apply(new Ident("x"), new Con(TypeStr.ABC))));
88 
89  HMType t1 = HM3.hm(x);
90  assertEquals("pair(v27:3,v23:\"abc\")",t1.str());
91  }
92 
93  @Test
94  public void test06() {
95  // recursive unification
96  // fn f => f f (fail)
97  Syntax x =
98  new Lambda("f", new Apply(new Ident("f"), new Ident("f")));
99  HMType t1 = HM3.hm(x);
100  // Not minimal form, but not too bad
101  assertEquals("{ { v23$ -> v22 } -> v22$ }",t1.str());
102  }
103 
104  @Test
105  public void test07() {
106  // let g = fn f => 5 in g g
107  Syntax x =
108  new Let("g",
109  new Lambda("f", new Con(TypeInt.con(5))),
110  new Apply(new Ident("g"), new Ident("g")));
111  HMType t1 = HM3.hm(x);
112  assertEquals("v25:5",t1.str());
113  }
114 
115  @Test
116  public void test08() {
117  // example that demonstrates generic and non-generic variables:
118  // fn g => let f = fn x => g in pair (f 3, f true)
119  Syntax syn =
120  new Lambda("g",
121  new Let("f",
122  new Lambda("x", new Ident("g")),
123  new Apply(
124  new Apply(new Ident("pair"),
125  new Apply(new Ident("f"), new Con(TypeInt.con(3)))
126  ),
127  new Apply(new Ident("f"), new Con(TypeInt.con(1))))));
128 
129  HMType t1 = HM3.hm(syn);
130  assertEquals("{ v21 -> pair(v21$,v21$) }",t1.str());
131  }
132 
133  @Test
134  public void test09() {
135  // Function composition
136  // fn f (fn g (fn arg (f g arg)))
137  Syntax syn =
138  new Lambda("f", new Lambda("g", new Lambda("arg", new Apply(new Ident("g"), new Apply(new Ident("f"), new Ident("arg"))))));
139 
140  HMType t1 = HM3.hm(syn);
141  assertEquals("{ { v23 -> v24 } -> { { v24$ -> v27 } -> { v23$ -> v27$ } } }",t1.str());
142  }
143 
144  @Test
145  public void test10() {
146  // Looking at when tvars are duplicated ("fresh" copies made).
147  // This is the "map" problem with a scalar instead of a collection.
148  // Takes a '{a->b}' and a 'a' for a couple of different prims.
149  // let map = { fun -> {x -> (fun x) }} in ((pair ((map str) 5)) ((map factor) 2.3))
150  Syntax syn =
151  new Let("map",
152  new Lambda("fun",
153  new Lambda("x",
154  new Apply(new Ident("fun"),new Ident("x")))),
155  new Apply(new Apply(new Ident("pair"),
156  new Apply(new Apply(new Ident("map"),
157  new Ident("str")), new Con(TypeInt.con(5)))),
158  new Apply(new Apply(new Ident("map"),
159  // "factor" a float returns a pair (mod,rem).
160  new Ident("factor")), new Con(TypeFlt.con(2.3)))));
161  HMType t1 = HM3.hm(syn);
162  assertEquals("pair(v36:*str,pair(v24:flt64,v24$))",t1.str());
163  }
164 
165  @Test(expected = RuntimeException.class)
166  public void test11() {
167  // Checking behavior when using "if/else" to merge two functions with
168  // sufficiently different signatures, then attempting to pass them to a map
169  // & calling internally.
170  // fcn takes a predicate 'p' and returns one of two fcns.
171  // let fcn = { p -> (((if/else p) {a -> pair[a,a]}) {b -> pair[b,pair[3,b]]}) } in
172  // map takes a function and an element (collection?) and applies it (applies to collection?)
173  // let map = { fun -> {x -> (fun x) }} in
174  // Should return either { p -> p ? [5,5] : [5,[3,5]] }
175  // { q -> ((map (fcn q)) 5) }
176 
177  Syntax syn =
178  new Let("fcn",
179  new Lambda("p",
180  new Apply(new Apply(new Apply(new Ident("if/else"),new Ident("p")), // p ?
181  new Lambda("a",
182  new Apply(new Apply(new Ident("pair"),new Ident("a")),
183  new Ident("a")))),
184  new Lambda("b",
185  new Apply(new Apply(new Ident("pair"),new Ident("b")),
186  new Apply(new Apply(new Ident("pair"),new Con(TypeInt.con(3))),
187  new Ident("b")))))),
188  new Let("map",
189  new Lambda("fun",
190  new Lambda("x",
191  new Apply(new Ident("fun"),new Ident("x")))),
192  new Lambda("q",
193  new Apply(new Apply(new Ident("map"),
194  new Apply(new Ident("fcn"),new Ident("q"))),
195  new Con(TypeInt.con(5))))));
196  HMType t1 = HM3.hm(syn);
197  // Cannot unify v29:5 and pair96(v97:3,v96$)
198  // Cannot unify 5 and (3,$) - unifying a 5 with a pair.
199  assertEquals("TBD",t1.str());
200  }
201 
202  @Test(expected = RuntimeException.class)
203  public void test12() {
204  // Want to constant-fold if/else, and drop the dead unification.
205  // So compute: (int->bool int) // ==0
206  // (flt->pair 1.2) // factor
207  // (P ? {==0} : {factor}) // Force unification {int/flt} -> {bool/pair}
208  // lambda P
209  // (((==0 1),(factor 1.2)), (((if/else P) ==0) factor))
210  Syntax syn =
211  new Lambda("p",
212  new Apply(new Apply(new Apply(new Ident("if/else"),new Ident("p")), // (((if/else p) ==0) factor)
213  new Ident("==0")),
214  new Ident("factor")));
215  HMType t1 = HM3.hm(syn);
216  assertEquals("Cannot unify v27:int1 and pair24(v23:Real,v23$)",t1.str());
217  }
218 }
com.cliffc.aa.HM.TestHM3.test05
void test05()
Definition: TestHM3.java:65
com.cliffc
com.cliffc.aa.type.TypeInt
Definition: TypeInt.java:9
com.cliffc.aa.HM.TestHM3.test08
void test08()
Definition: TestHM3.java:116
com.cliffc.aa.type.TypeFlt
Definition: TypeFlt.java:9
com.cliffc.aa.HM.TestHM3.test06
void test06()
Definition: TestHM3.java:94
com.cliffc.aa.type.TypeInt.con
static TypeInt con(long con)
Definition: TypeInt.java:37
com.cliffc.aa.HM.TestHM3.reset
void reset()
Definition: TestHM3.java:12
com.cliffc.aa.HM.TestHM3.test02
void test02()
Definition: TestHM3.java:28
com.cliffc.aa.HM.HM3
Definition: HM3.java:31
Test
com.cliffc.aa.HM.TestHM3.test11
void test11()
Definition: TestHM3.java:166
com.cliffc.aa.HM.TestHM3.test09
void test09()
Definition: TestHM3.java:134
com.cliffc.aa.type.TypeFlt.con
static Type con(double con)
Definition: TypeFlt.java:36
com.cliffc.aa.HM.TestHM3.test07
void test07()
Definition: TestHM3.java:105
com.cliffc.aa.HM.TestHM3.test01
void test01()
Definition: TestHM3.java:21
com.cliffc.aa.HM.TestHM3.test05a
void test05a()
Definition: TestHM3.java:80
com.cliffc.aa.type.TypeStr.ABC
static final TypeStr ABC
Definition: TypeStr.java:47
com.cliffc.aa.HM.TestHM3.test03
void test03()
Definition: TestHM3.java:35
com.cliffc.aa.HM.HM3.reset
static void reset()
Definition: HM3.java:80
com.cliffc.aa.type.TypeStr
Definition: TypeStr.java:14
com.cliffc.aa.HM.TestHM3.test00
void test00()
Definition: TestHM3.java:15
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.HM.TestHM3.test04
void test04()
Definition: TestHM3.java:53
com.cliffc.aa.HM.TestHM3.test10
void test10()
Definition: TestHM3.java:145
com.cliffc.aa.HM.TestHM3.test12
void test12()
Definition: TestHM3.java:203
com.cliffc.aa.HM
Definition: HM.java:1
com.cliffc.aa.HM.HM3.hm
static HMType hm(Syntax prog)
Definition: HM3.java:34
com.cliffc.aa.HM.TestHM3
Definition: TestHM3.java:10
com
com.cliffc.aa.type
Definition: Bits.java:1