aa
TestHM2.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.HM2.*;
8 import static org.junit.Assert.assertEquals;
9 
10 public class TestHM2 {
11 
12  @Before public void reset() { HM2.reset(); }
13 
14  @Test(expected = RuntimeException.class)
15  public void test00() {
16  Syntax syn = new Ident("fred");
17  HM2.hm(syn);
18  }
19 
20  @Test
21  public void test01() {
22  Syntax syn = new Con(TypeInt.con(3));
23  HMVar t = (HMVar)HM2.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 = HM2.hm(syn);
31  assertEquals("{ v9 -> pair(v8:3,v9) }",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 = HM2.hm(fact);
49  assertEquals("{ v25:int64 -> v25:int64 }",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 = HM2.hm(x);
61  assertEquals("{ { v11:all -> v9 } -> pair(v9,v9) }",t1.str());
62  }
63 
64  @Test
65  public void test05() {
66  // ({ x -> (pair (x 3) (x "abc")) } {x->x})
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 = HM2.hm(x);
75  assertEquals("pair(v9:all,v9:all)",t1.str());
76  }
77 
78 
79  @Test(expected = RuntimeException.class)
80  public void test06() {
81  // recursive unification
82  // fn f => f f (fail)
83  Syntax x =
84  new Lambda("f", new Apply(new Ident("f"), new Ident("f")));
85  HM2.hm(x);
86  }
87 
88  @Test
89  public void test07() {
90  // let g = fn f => 5 in g g
91  Syntax x =
92  new Let("g",
93  new Lambda("f", new Con(TypeInt.con(5))),
94  new Apply(new Ident("g"), new Ident("g")));
95  HMType t1 = HM2.hm(x);
96  assertEquals("v12:5",t1.str());
97  }
98 
99  @Test
100  public void test08() {
101  // example that demonstrates generic and non-generic variables:
102  // fn g => let f = fn x => g in pair (f 3, f true)
103  Syntax syn =
104  new Lambda("g",
105  new Let("f",
106  new Lambda("x", new Ident("g")),
107  new Apply(
108  new Apply(new Ident("pair"),
109  new Apply(new Ident("f"), new Con(TypeInt.con(3)))
110  ),
111  new Apply(new Ident("f"), new Con(TypeInt.con(1))))));
112 
113  HMType t1 = HM2.hm(syn);
114  assertEquals("{ v11 -> pair(v11,v11) }",t1.str());
115  }
116 
117  @Test
118  public void test09() {
119  // Function composition
120  // fn f (fn g (fn arg (f g arg)))
121  Syntax syn =
122  new Lambda("f", new Lambda("g", new Lambda("arg", new Apply(new Ident("g"), new Apply(new Ident("f"), new Ident("arg"))))));
123 
124  HMType t1 = HM2.hm(syn);
125  assertEquals("{ { v10 -> v11 } -> { { v11 -> v12 } -> { v10 -> v12 } } }",t1.str());
126  }
127 
128 
129  @Test
130  public void test10() {
131  // Looking at when tvars are duplicated ("fresh" copies made).
132  // This is the "map" problem with a scalar instead of a collection.
133  // Takes a '{a->b}' and a 'a' for a couple of different prims.
134  // let map = { fun -> {x -> (fun x) }} in ((pair ((map str) 5)) ((map factor) 2.3))
135  Syntax syn =
136  new Let("map",
137  new Lambda("fun",
138  new Lambda("x",
139  new Apply(new Ident("fun"),new Ident("x")))),
140  new Apply(new Apply(new Ident("pair"),
141  new Apply(new Apply(new Ident("map"),
142  new Ident("str")), new Con(TypeInt.con(5)))),
143  new Apply(new Apply(new Ident("map"),
144  // "factor" a float returns a pair (mod,rem).
145  new Ident("factor")), new Con(TypeFlt.con(2.3)))));
146  HMType t1 = HM2.hm(syn);
147  assertEquals("pair(v12:*str,pair(v26:flt64,v26:flt64))",t1.str());
148  }
149 
150  @Test(expected = RuntimeException.class)
151  public void test11() {
152  // Checking behavior when using "if/else" to merge two functions with
153  // sufficiently different signatures, then attempting to pass them to a map
154  // & calling internally.
155  // fcn takes a predicate 'p' and returns one of two fcns.
156  // let fcn = { p -> (((if/else p) {a -> pair[a,a]}) {b -> pair[b,pair[3,b]]}) } in
157  // map takes a function and an element (collection?) and applies it (applies to collection?)
158  // let map = { fun -> {x -> (fun x) }} in
159  // Should return either { p -> p ? [5,5] : [5,[3,5]] }
160  // { q -> ((map (fcn q)) 5) }
161  Syntax syn =
162  new Let("fcn",
163  new Lambda("p",
164  new Apply(new Apply(new Apply(new Ident("if/else"),new Ident("p")), // p ?
165  new Lambda("a",
166  new Apply(new Apply(new Ident("pair"),new Ident("a")),
167  new Ident("a")))),
168  new Lambda("b",
169  new Apply(new Apply(new Ident("pair"),new Ident("b")),
170  new Apply(new Apply(new Ident("pair"),new Con(TypeInt.con(3))),
171  new Ident("b")))))),
172  new Let("map",
173  new Lambda("fun",
174  new Lambda("x",
175  new Apply(new Ident("fun"),new Ident("x")))),
176  new Lambda("q",
177  new Apply(new Apply(new Ident("map"),
178  new Apply(new Ident("fcn"),new Ident("q"))),
179  new Con(TypeInt.con(5))))));
180  // Ultimately, unifies "a" with "pair[3,a]" which throws recursive unification.
181  HMType t1 = HM2.hm(syn);
182  assertEquals("TBD",t1.str());
183  }
184 
185 }
com.cliffc
com.cliffc.aa.HM.TestHM2.test02
void test02()
Definition: TestHM2.java:28
com.cliffc.aa.HM.TestHM2.test04
void test04()
Definition: TestHM2.java:53
com.cliffc.aa.HM.TestHM2
Definition: TestHM2.java:10
com.cliffc.aa.HM.TestHM2.reset
void reset()
Definition: TestHM2.java:12
com.cliffc.aa.HM.TestHM2.test03
void test03()
Definition: TestHM2.java:35
com.cliffc.aa.type.TypeInt
Definition: TypeInt.java:9
com.cliffc.aa.type.TypeFlt
Definition: TypeFlt.java:9
com.cliffc.aa.type.TypeInt.con
static TypeInt con(long con)
Definition: TypeInt.java:37
Test
com.cliffc.aa.type.TypeFlt.con
static Type con(double con)
Definition: TypeFlt.java:36
com.cliffc.aa.type.TypeStr.ABC
static final TypeStr ABC
Definition: TypeStr.java:47
com.cliffc.aa.HM.TestHM2.test09
void test09()
Definition: TestHM2.java:118
com.cliffc.aa.HM.TestHM2.test06
void test06()
Definition: TestHM2.java:80
com.cliffc.aa.HM.HM2.reset
static void reset()
Definition: HM2.java:100
com.cliffc.aa.type.TypeStr
Definition: TypeStr.java:14
com.cliffc.aa.HM.TestHM2.test08
void test08()
Definition: TestHM2.java:100
com.cliffc.aa.HM.TestHM2.test01
void test01()
Definition: TestHM2.java:21
com.cliffc.aa.HM.TestHM2.test07
void test07()
Definition: TestHM2.java:89
com.cliffc.aa.HM.TestHM2.test00
void test00()
Definition: TestHM2.java:15
com.cliffc.aa.HM.TestHM2.test11
void test11()
Definition: TestHM2.java:151
com.cliffc.aa.HM.TestHM2.test05
void test05()
Definition: TestHM2.java:65
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.HM.HM2
Definition: HM2.java:67
com.cliffc.aa.HM
Definition: HM.java:1
com.cliffc.aa.HM.HM2.hm
static HMType hm(Syntax prog)
Definition: HM2.java:70
com.cliffc.aa.HM.TestHM2.test10
void test10()
Definition: TestHM2.java:130
com
com.cliffc.aa.type
Definition: Bits.java:1