finitio 0.7.0 → 0.8.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +40 -41
- data/lib/finitio/generation.rb +106 -0
- data/lib/finitio/generation/ad_type.rb +10 -0
- data/lib/finitio/generation/alias_type.rb +9 -0
- data/lib/finitio/generation/any_type.rb +11 -0
- data/lib/finitio/generation/builtin_type.rb +9 -0
- data/lib/finitio/generation/hash_based_type.rb +15 -0
- data/lib/finitio/generation/heuristic.rb +8 -0
- data/lib/finitio/generation/heuristic/constant.rb +30 -0
- data/lib/finitio/generation/heuristic/random.rb +52 -0
- data/lib/finitio/generation/rel_based_type.rb +13 -0
- data/lib/finitio/generation/seq_type.rb +13 -0
- data/lib/finitio/generation/set_type.rb +13 -0
- data/lib/finitio/generation/sub_type.rb +9 -0
- data/lib/finitio/generation/union_type.rb +10 -0
- data/lib/finitio/inference.rb +51 -0
- data/lib/finitio/support.rb +18 -0
- data/lib/finitio/support/attribute.rb +8 -0
- data/lib/finitio/support/compilation.rb +18 -18
- data/lib/finitio/support/contract.rb +8 -0
- data/lib/finitio/support/fetch_scope.rb +19 -0
- data/lib/finitio/support/heading.rb +36 -1
- data/lib/finitio/syntax.rb +1 -1
- data/lib/finitio/syntax/lexer.citrus +1 -1
- data/lib/finitio/syntax/type.rb +2 -0
- data/lib/finitio/syntax/type/high_order_type_instantiation.rb +29 -0
- data/lib/finitio/syntax/type/high_order_vars.rb +16 -0
- data/lib/finitio/syntax/type/type_def.rb +11 -1
- data/lib/finitio/syntax/types.citrus +14 -1
- data/lib/finitio/system.rb +11 -1
- data/lib/finitio/type.rb +19 -0
- data/lib/finitio/type/ad_type.rb +8 -0
- data/lib/finitio/type/alias_type.rb +8 -0
- data/lib/finitio/type/any_type.rb +12 -0
- data/lib/finitio/type/builtin_type.rb +4 -0
- data/lib/finitio/type/collection_type.rb +15 -0
- data/lib/finitio/type/heading_based_type.rb +17 -0
- data/lib/finitio/type/high_order_type.rb +39 -0
- data/lib/finitio/type/multi_relation_type.rb +4 -0
- data/lib/finitio/type/multi_tuple_type.rb +4 -0
- data/lib/finitio/type/proxy_type.rb +10 -20
- data/lib/finitio/type/relation_type.rb +4 -0
- data/lib/finitio/type/seq_type.rb +1 -1
- data/lib/finitio/type/struct_type.rb +8 -0
- data/lib/finitio/type/sub_type.rb +8 -0
- data/lib/finitio/type/tuple_type.rb +4 -0
- data/lib/finitio/type/union_type.rb +19 -0
- data/lib/finitio/version.rb +1 -1
- data/spec/generation/test_generation.rb +169 -0
- data/spec/heading/test_looks_similar.rb +45 -0
- data/spec/heading/test_suppremum.rb +56 -0
- data/spec/inference/test_inference.rb +42 -0
- data/spec/spec_helper.rb +31 -6
- data/spec/support/test_compare_attrs.rb +67 -0
- data/spec/syntax/test_compile.rb +57 -0
- data/spec/type/ad_type/test_initialize.rb +1 -8
- data/spec/type/relation_type/test_suppremum.rb +104 -0
- data/spec/type/seq_type/test_suppremum.rb +54 -0
- data/spec/type/set_type/test_suppremum.rb +54 -0
- data/spec/type/test_suppremum.rb +49 -0
- data/spec/type/test_unconstrained.rb +150 -0
- data/spec/type/tuple_type/test_suppremum.rb +119 -0
- data/spec/type/union_type/test_suppremum.rb +51 -0
- data/tasks/test.rake +1 -1
- metadata +183 -144
- data/spec/type/proxy_type/test_delegation.rb +0 -37
- data/spec/type/proxy_type/test_resolve.rb +0 -29
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe SeqType, "suppremum" do
|
4
|
+
|
5
|
+
subject{
|
6
|
+
left.suppremum(right)
|
7
|
+
}
|
8
|
+
|
9
|
+
let(:left) {
|
10
|
+
SeqType.new(intType)
|
11
|
+
}
|
12
|
+
|
13
|
+
context 'when right is equal' do
|
14
|
+
let(:right) {
|
15
|
+
SeqType.new(intType)
|
16
|
+
}
|
17
|
+
|
18
|
+
it 'keeps left' do
|
19
|
+
expect(subject).to be(left)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when right is a set type of same element type' do
|
24
|
+
let(:right) {
|
25
|
+
SetType.new(intType)
|
26
|
+
}
|
27
|
+
|
28
|
+
it 'keeps left' do
|
29
|
+
expect(subject).to eql(SeqType.new(intType))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when right is not a seq type' do
|
34
|
+
let(:right) {
|
35
|
+
stringType
|
36
|
+
}
|
37
|
+
|
38
|
+
it 'builds a UnionType' do
|
39
|
+
expect(subject).to eql(UnionType.new [left, right])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when right is a seq type of a different element type' do
|
44
|
+
let(:right) {
|
45
|
+
SeqType.new(floatType)
|
46
|
+
}
|
47
|
+
|
48
|
+
it 'builds a SeqType[UnionType]' do
|
49
|
+
expect(subject).to eql(SeqType.new(UnionType.new [intType, floatType]))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe SetType, "suppremum" do
|
4
|
+
|
5
|
+
subject{
|
6
|
+
left.suppremum(right)
|
7
|
+
}
|
8
|
+
|
9
|
+
let(:left) {
|
10
|
+
SetType.new(intType)
|
11
|
+
}
|
12
|
+
|
13
|
+
context 'when right is equal' do
|
14
|
+
let(:right) {
|
15
|
+
SetType.new(intType)
|
16
|
+
}
|
17
|
+
|
18
|
+
it 'keeps left' do
|
19
|
+
expect(subject).to be(left)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when right is not a seq type' do
|
24
|
+
let(:right) {
|
25
|
+
stringType
|
26
|
+
}
|
27
|
+
|
28
|
+
it 'builds a UnionType' do
|
29
|
+
expect(subject).to eql(UnionType.new [left, right])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when right is a set type of same element type' do
|
34
|
+
let(:right) {
|
35
|
+
SeqType.new(intType)
|
36
|
+
}
|
37
|
+
|
38
|
+
it 'keeps right' do
|
39
|
+
expect(subject).to eql(SetType.new intType)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when right is a seq type of a different element type' do
|
44
|
+
let(:right) {
|
45
|
+
SetType.new(floatType)
|
46
|
+
}
|
47
|
+
|
48
|
+
it 'builds a SetType[UnionType]' do
|
49
|
+
expect(subject).to eql(SetType.new(UnionType.new [intType, floatType]))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe Type, "suppremum" do
|
4
|
+
|
5
|
+
subject{
|
6
|
+
left.suppremum(right)
|
7
|
+
}
|
8
|
+
|
9
|
+
let(:left){
|
10
|
+
intType
|
11
|
+
}
|
12
|
+
|
13
|
+
context 'when both are equal' do
|
14
|
+
let(:right){
|
15
|
+
intType
|
16
|
+
}
|
17
|
+
|
18
|
+
it 'works' do
|
19
|
+
expect(subject).to be(left)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when they are different' do
|
24
|
+
let(:right){
|
25
|
+
nilType
|
26
|
+
}
|
27
|
+
|
28
|
+
it 'works' do
|
29
|
+
expect(subject).to be_a(UnionType)
|
30
|
+
expect(subject.candidates).to eql([left, right])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when one is any' do
|
35
|
+
let(:right){
|
36
|
+
anyType
|
37
|
+
}
|
38
|
+
|
39
|
+
it 'works' do
|
40
|
+
expect(subject).to eql(anyType)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'works the other way round' do
|
44
|
+
expect(anyType.suppremum(left)).to eql(anyType)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe Type, "unconstrained" do
|
4
|
+
|
5
|
+
subject{
|
6
|
+
type.unconstrained
|
7
|
+
}
|
8
|
+
|
9
|
+
context "on Any" do
|
10
|
+
let(:type){
|
11
|
+
ANY_TYPE
|
12
|
+
}
|
13
|
+
|
14
|
+
it 'returns the type itself by default' do
|
15
|
+
expect(subject).to be(type)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "on a Builtin" do
|
20
|
+
let(:type){
|
21
|
+
intType
|
22
|
+
}
|
23
|
+
|
24
|
+
it 'returns the type itself by default' do
|
25
|
+
expect(subject).to be(type)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'on a sub type' do
|
30
|
+
let(:type){
|
31
|
+
pos_byte
|
32
|
+
}
|
33
|
+
|
34
|
+
it 'returns the most unconstrained super type' do
|
35
|
+
expect(subject).to be(intType)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'on an alias type' do
|
40
|
+
let(:type){
|
41
|
+
AliasType.new(pos_byte, "alias")
|
42
|
+
}
|
43
|
+
|
44
|
+
it 'returns an alias on the most unconstrained super type' do
|
45
|
+
expect(subject).to be_a(AliasType)
|
46
|
+
expect(subject.target).to be(intType)
|
47
|
+
expect(subject.name).to eql("alias")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'on an proxy type' do
|
52
|
+
let(:type){
|
53
|
+
ProxyType.new("pos_byte", pos_byte)
|
54
|
+
}
|
55
|
+
|
56
|
+
it 'returns the most unconstrained super type' do
|
57
|
+
expect(subject).to be(intType)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'on an seq type' do
|
62
|
+
let(:type){
|
63
|
+
SeqType.new(pos_byte)
|
64
|
+
}
|
65
|
+
|
66
|
+
it 'returns the most unconstrained super type' do
|
67
|
+
expect(subject).to be_a(SeqType)
|
68
|
+
expect(subject.elm_type).to be(intType)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'on an set type' do
|
73
|
+
let(:type){
|
74
|
+
SetType.new(pos_byte)
|
75
|
+
}
|
76
|
+
|
77
|
+
it 'returns the most unconstrained super type' do
|
78
|
+
expect(subject).to be_a(SetType)
|
79
|
+
expect(subject.elm_type).to be(intType)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'on an tuple type' do
|
84
|
+
let(:type){
|
85
|
+
TupleType.new(Heading.new [Attribute.new(:i, pos_byte)])
|
86
|
+
}
|
87
|
+
|
88
|
+
it 'returns the most unconstrained super type' do
|
89
|
+
expect(subject).to be_a(TupleType)
|
90
|
+
expect(subject.heading[:i].type).to be(intType)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'on an relation type' do
|
95
|
+
let(:type){
|
96
|
+
RelationType.new(Heading.new [Attribute.new(:i, pos_byte)])
|
97
|
+
}
|
98
|
+
|
99
|
+
it 'returns the most unconstrained super type' do
|
100
|
+
expect(subject).to be_a(RelationType)
|
101
|
+
expect(subject.heading[:i].type).to be(intType)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'on an union type' do
|
106
|
+
let(:type){
|
107
|
+
UnionType.new([pos_byte])
|
108
|
+
}
|
109
|
+
|
110
|
+
it 'returns the most unconstrained super type' do
|
111
|
+
expect(subject).to be_a(UnionType)
|
112
|
+
expect(subject.candidates).to eql([intType])
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'on an struct type' do
|
117
|
+
let(:type){
|
118
|
+
StructType.new([pos_byte])
|
119
|
+
}
|
120
|
+
|
121
|
+
it 'returns the most unconstrained super type' do
|
122
|
+
expect(subject).to be_a(StructType)
|
123
|
+
expect(subject.component_types).to eql([intType])
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'on a high-order type' do
|
128
|
+
let(:type){
|
129
|
+
HighOrderType.new(["V"], pos_byte)
|
130
|
+
}
|
131
|
+
|
132
|
+
it 'returns the most unconstrained super type' do
|
133
|
+
expect(subject).to be_a(HighOrderType)
|
134
|
+
expect(subject.defn).to be(intType)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'on an AD type' do
|
139
|
+
let(:type){
|
140
|
+
AdType.new(Color, [rgb_contract])
|
141
|
+
}
|
142
|
+
|
143
|
+
it 'returns the most unconstrained super type' do
|
144
|
+
expect(subject).to be_a(AdType)
|
145
|
+
expect(subject.contracts).to eql([rgb_contract.unconstrained])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe TupleType, "suppremum" do
|
4
|
+
|
5
|
+
subject{
|
6
|
+
left.suppremum(right)
|
7
|
+
}
|
8
|
+
|
9
|
+
let(:heading){
|
10
|
+
Heading.new([Attribute.new(:a, intType),
|
11
|
+
Attribute.new(:b, stringType)])
|
12
|
+
}
|
13
|
+
|
14
|
+
let(:left){
|
15
|
+
TupleType.new(heading)
|
16
|
+
}
|
17
|
+
|
18
|
+
context 'when right is not a tuple type' do
|
19
|
+
let(:right){
|
20
|
+
stringType
|
21
|
+
}
|
22
|
+
|
23
|
+
it 'builds a union type' do
|
24
|
+
expect(subject).to be_a(UnionType)
|
25
|
+
expect(subject.candidates).to eql([left, right])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when right is an equal tuple type' do
|
30
|
+
let(:h2){
|
31
|
+
Heading.new([Attribute.new(:c, intType),
|
32
|
+
Attribute.new(:d, stringType)])
|
33
|
+
}
|
34
|
+
let(:right) {
|
35
|
+
TupleType.new(h2)
|
36
|
+
}
|
37
|
+
|
38
|
+
it 'builds a union type' do
|
39
|
+
expect(subject).to be_a(UnionType)
|
40
|
+
expect(subject.candidates).to eql([left, right])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when right is a completely different tuple type' do
|
45
|
+
let(:right){
|
46
|
+
TupleType.new(heading)
|
47
|
+
}
|
48
|
+
|
49
|
+
it 'keeps left' do
|
50
|
+
expect(subject).to be(left)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when right is an non-equal tuple type but compatible with TupleType' do
|
55
|
+
let(:heading2){
|
56
|
+
Heading.new([Attribute.new(:a, nilType),
|
57
|
+
Attribute.new(:b, stringType)])
|
58
|
+
}
|
59
|
+
|
60
|
+
let(:right){
|
61
|
+
TupleType.new(heading2)
|
62
|
+
}
|
63
|
+
|
64
|
+
it 'builds the suppremum as expected' do
|
65
|
+
expect(subject).to be_a(TupleType)
|
66
|
+
expect(subject.heading[:a].type).to eql(UnionType.new [intType,nilType])
|
67
|
+
expect(subject.heading[:b].type).to eql(stringType)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when right is an non-equal tuple type yielding a MultiTupleType' do
|
72
|
+
let(:heading2){
|
73
|
+
Heading.new([Attribute.new(:c, nilType),
|
74
|
+
Attribute.new(:b, stringType)])
|
75
|
+
}
|
76
|
+
|
77
|
+
let(:right){
|
78
|
+
TupleType.new(heading2)
|
79
|
+
}
|
80
|
+
|
81
|
+
it 'builds the suppremum as expected' do
|
82
|
+
expect(subject).to be_a(MultiTupleType)
|
83
|
+
expect(subject.heading[:a].type).to eql(intType)
|
84
|
+
expect(subject.heading[:a].required).to eql(false)
|
85
|
+
expect(subject.heading[:b].type).to eql(stringType)
|
86
|
+
expect(subject.heading[:b].required).to eql(true)
|
87
|
+
expect(subject.heading[:c].type).to eql(nilType)
|
88
|
+
expect(subject.heading[:c].required).to eql(false)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'when right is an non-equal tuple type yielding a MultiTupleType II' do
|
93
|
+
let(:heading2){
|
94
|
+
Heading.new([Attribute.new(:a, nilType, false),
|
95
|
+
Attribute.new(:b, stringType)])
|
96
|
+
}
|
97
|
+
|
98
|
+
let(:right){
|
99
|
+
MultiTupleType.new(heading2)
|
100
|
+
}
|
101
|
+
|
102
|
+
it 'builds the suppremum as expected' do
|
103
|
+
expect(subject).to be_a(MultiTupleType)
|
104
|
+
expect(subject.heading[:a].type).to eql(UnionType.new [intType,nilType])
|
105
|
+
expect(subject.heading[:a].required).to eql(false)
|
106
|
+
expect(subject.heading[:b].type).to eql(stringType)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'works the other way round too' do
|
110
|
+
subject = right.suppremum(left)
|
111
|
+
expect(subject).to be_a(MultiTupleType)
|
112
|
+
expect(subject.heading[:a].type).to eql(UnionType.new [intType,nilType])
|
113
|
+
expect(subject.heading[:a].required).to eql(false)
|
114
|
+
expect(subject.heading[:b].type).to eql(stringType)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe UnionType, "suppremum" do
|
4
|
+
|
5
|
+
subject{
|
6
|
+
left.suppremum(right)
|
7
|
+
}
|
8
|
+
|
9
|
+
let(:left){
|
10
|
+
UnionType.new([intType, nilType])
|
11
|
+
}
|
12
|
+
|
13
|
+
context 'when right is not a union type' do
|
14
|
+
let(:right){
|
15
|
+
stringType
|
16
|
+
}
|
17
|
+
|
18
|
+
it 'works' do
|
19
|
+
expect(subject).to be_a(UnionType)
|
20
|
+
expect(subject.candidates).to eql(left.candidates + [right])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when right is a union type' do
|
25
|
+
let(:right){
|
26
|
+
UnionType.new([stringType, nilType])
|
27
|
+
}
|
28
|
+
|
29
|
+
it 'works' do
|
30
|
+
expect(subject).to be_a(UnionType)
|
31
|
+
expect(subject.candidates).to eql([intType, nilType, stringType])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when union type is on the right' do
|
36
|
+
let(:left){
|
37
|
+
stringType
|
38
|
+
}
|
39
|
+
|
40
|
+
let(:right){
|
41
|
+
UnionType.new([intType, nilType])
|
42
|
+
}
|
43
|
+
|
44
|
+
it 'works' do
|
45
|
+
expect(subject).to be_a(UnionType)
|
46
|
+
expect(subject.candidates).to eql([intType, nilType, stringType])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|