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.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +10 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +40 -41
  5. data/lib/finitio/generation.rb +106 -0
  6. data/lib/finitio/generation/ad_type.rb +10 -0
  7. data/lib/finitio/generation/alias_type.rb +9 -0
  8. data/lib/finitio/generation/any_type.rb +11 -0
  9. data/lib/finitio/generation/builtin_type.rb +9 -0
  10. data/lib/finitio/generation/hash_based_type.rb +15 -0
  11. data/lib/finitio/generation/heuristic.rb +8 -0
  12. data/lib/finitio/generation/heuristic/constant.rb +30 -0
  13. data/lib/finitio/generation/heuristic/random.rb +52 -0
  14. data/lib/finitio/generation/rel_based_type.rb +13 -0
  15. data/lib/finitio/generation/seq_type.rb +13 -0
  16. data/lib/finitio/generation/set_type.rb +13 -0
  17. data/lib/finitio/generation/sub_type.rb +9 -0
  18. data/lib/finitio/generation/union_type.rb +10 -0
  19. data/lib/finitio/inference.rb +51 -0
  20. data/lib/finitio/support.rb +18 -0
  21. data/lib/finitio/support/attribute.rb +8 -0
  22. data/lib/finitio/support/compilation.rb +18 -18
  23. data/lib/finitio/support/contract.rb +8 -0
  24. data/lib/finitio/support/fetch_scope.rb +19 -0
  25. data/lib/finitio/support/heading.rb +36 -1
  26. data/lib/finitio/syntax.rb +1 -1
  27. data/lib/finitio/syntax/lexer.citrus +1 -1
  28. data/lib/finitio/syntax/type.rb +2 -0
  29. data/lib/finitio/syntax/type/high_order_type_instantiation.rb +29 -0
  30. data/lib/finitio/syntax/type/high_order_vars.rb +16 -0
  31. data/lib/finitio/syntax/type/type_def.rb +11 -1
  32. data/lib/finitio/syntax/types.citrus +14 -1
  33. data/lib/finitio/system.rb +11 -1
  34. data/lib/finitio/type.rb +19 -0
  35. data/lib/finitio/type/ad_type.rb +8 -0
  36. data/lib/finitio/type/alias_type.rb +8 -0
  37. data/lib/finitio/type/any_type.rb +12 -0
  38. data/lib/finitio/type/builtin_type.rb +4 -0
  39. data/lib/finitio/type/collection_type.rb +15 -0
  40. data/lib/finitio/type/heading_based_type.rb +17 -0
  41. data/lib/finitio/type/high_order_type.rb +39 -0
  42. data/lib/finitio/type/multi_relation_type.rb +4 -0
  43. data/lib/finitio/type/multi_tuple_type.rb +4 -0
  44. data/lib/finitio/type/proxy_type.rb +10 -20
  45. data/lib/finitio/type/relation_type.rb +4 -0
  46. data/lib/finitio/type/seq_type.rb +1 -1
  47. data/lib/finitio/type/struct_type.rb +8 -0
  48. data/lib/finitio/type/sub_type.rb +8 -0
  49. data/lib/finitio/type/tuple_type.rb +4 -0
  50. data/lib/finitio/type/union_type.rb +19 -0
  51. data/lib/finitio/version.rb +1 -1
  52. data/spec/generation/test_generation.rb +169 -0
  53. data/spec/heading/test_looks_similar.rb +45 -0
  54. data/spec/heading/test_suppremum.rb +56 -0
  55. data/spec/inference/test_inference.rb +42 -0
  56. data/spec/spec_helper.rb +31 -6
  57. data/spec/support/test_compare_attrs.rb +67 -0
  58. data/spec/syntax/test_compile.rb +57 -0
  59. data/spec/type/ad_type/test_initialize.rb +1 -8
  60. data/spec/type/relation_type/test_suppremum.rb +104 -0
  61. data/spec/type/seq_type/test_suppremum.rb +54 -0
  62. data/spec/type/set_type/test_suppremum.rb +54 -0
  63. data/spec/type/test_suppremum.rb +49 -0
  64. data/spec/type/test_unconstrained.rb +150 -0
  65. data/spec/type/tuple_type/test_suppremum.rb +119 -0
  66. data/spec/type/union_type/test_suppremum.rb +51 -0
  67. data/tasks/test.rake +1 -1
  68. metadata +183 -144
  69. data/spec/type/proxy_type/test_delegation.rb +0 -37
  70. 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