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
 
    
        data/lib/finitio/type.rb
    CHANGED
    
    | 
         @@ -54,6 +54,20 @@ module Finitio 
     | 
|
| 
       54 
54 
     | 
    
         
             
                  raise NotImplementedError, "Missing #{self.class.name}#dress"
         
     | 
| 
       55 
55 
     | 
    
         
             
                end
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
      
 57 
     | 
    
         
            +
                def suppremum(other)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  return self if other == self
         
     | 
| 
      
 59 
     | 
    
         
            +
                  other._suppremum(self)
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def _suppremum(other)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  UnionType.new([other, self])
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
                protected :_suppremum
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 68 
     | 
    
         
            +
                  self
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
       57 
71 
     | 
    
         
             
                def to_s
         
     | 
| 
       58 
72 
     | 
    
         
             
                  name.to_s
         
     | 
| 
       59 
73 
     | 
    
         
             
                end
         
     | 
| 
         @@ -64,6 +78,10 @@ module Finitio 
     | 
|
| 
       64 
78 
     | 
    
         
             
                  }
         
     | 
| 
       65 
79 
     | 
    
         
             
                end
         
     | 
| 
       66 
80 
     | 
    
         | 
| 
      
 81 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  raise NotImplementedError, "resolve_proxies must be overriden"
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
       67 
85 
     | 
    
         
             
              protected
         
     | 
| 
       68 
86 
     | 
    
         | 
| 
       69 
87 
     | 
    
         
             
                def set_equal?(s1, s2)
         
     | 
| 
         @@ -94,3 +112,4 @@ require_relative 'type/multi_tuple_type' 
     | 
|
| 
       94 
112 
     | 
    
         
             
            require_relative 'type/relation_type'
         
     | 
| 
       95 
113 
     | 
    
         
             
            require_relative 'type/multi_relation_type'
         
     | 
| 
       96 
114 
     | 
    
         
             
            require_relative 'type/ad_type'
         
     | 
| 
      
 115 
     | 
    
         
            +
            require_relative 'type/high_order_type'
         
     | 
    
        data/lib/finitio/type/ad_type.rb
    CHANGED
    
    | 
         @@ -144,5 +144,13 @@ module Finitio 
     | 
|
| 
       144 
144 
     | 
    
         
             
                end
         
     | 
| 
       145 
145 
     | 
    
         
             
                alias :eql? :==
         
     | 
| 
       146 
146 
     | 
    
         | 
| 
      
 147 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 148 
     | 
    
         
            +
                  AdType.new(ruby_type, contracts.map{|t| t.resolve_proxies(system)}, name, metadata)
         
     | 
| 
      
 149 
     | 
    
         
            +
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 152 
     | 
    
         
            +
                  AdType.new(ruby_type, contracts.map{|c| c.unconstrained}, name, metadata)
         
     | 
| 
      
 153 
     | 
    
         
            +
                end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
       147 
155 
     | 
    
         
             
              end # class AdType
         
     | 
| 
       148 
156 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -33,5 +33,13 @@ module Finitio 
     | 
|
| 
       33 
33 
     | 
    
         
             
                  end
         
     | 
| 
       34 
34 
     | 
    
         
             
                end
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
      
 36 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  AliasType.new(target.resolve_proxies(system), name, metadata)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 41 
     | 
    
         
            +
                  AliasType.new(target.unconstrained, name, metadata)
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
       36 
44 
     | 
    
         
             
              end # class AliasType
         
     | 
| 
       37 
45 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -38,6 +38,14 @@ module Finitio 
     | 
|
| 
       38 
38 
     | 
    
         
             
                  value
         
     | 
| 
       39 
39 
     | 
    
         
             
                end
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
      
 41 
     | 
    
         
            +
                def suppremum(other)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  self
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def _suppremum(other)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  self
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
       41 
49 
     | 
    
         
             
                def ==(other)
         
     | 
| 
       42 
50 
     | 
    
         
             
                  super || other.is_a?(AnyType)
         
     | 
| 
       43 
51 
     | 
    
         
             
                end
         
     | 
| 
         @@ -47,5 +55,9 @@ module Finitio 
     | 
|
| 
       47 
55 
     | 
    
         
             
                  self.class.hash ^ 37
         
     | 
| 
       48 
56 
     | 
    
         
             
                end
         
     | 
| 
       49 
57 
     | 
    
         | 
| 
      
 58 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  self
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
       50 
62 
     | 
    
         
             
              end # class AnyType
         
     | 
| 
       51 
63 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -20,5 +20,20 @@ module Finitio 
     | 
|
| 
       20 
20 
     | 
    
         
             
                  self.class.hash ^ self.elm_type.hash
         
     | 
| 
       21 
21 
     | 
    
         
             
                end
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
      
 23 
     | 
    
         
            +
                def suppremum(other)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  return super unless other.is_a?(CollectionType)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  return self if other.is_a?(CollectionType) && elm_type == other.elm_type
         
     | 
| 
      
 26 
     | 
    
         
            +
                  builder = self.class == other.class ? self.class : SeqType
         
     | 
| 
      
 27 
     | 
    
         
            +
                  builder.new(elm_type.suppremum(other.elm_type))
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  self.class.new(elm_type.resolve_proxies(system), name, metadata)
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 35 
     | 
    
         
            +
                  self.class.new(elm_type.unconstrained, name, metadata)
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       23 
38 
     | 
    
         
             
              end # module CollectionType
         
     | 
| 
       24 
39 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -15,6 +15,15 @@ module Finitio 
     | 
|
| 
       15 
15 
     | 
    
         
             
                  heading.fetch(attrname)
         
     | 
| 
       16 
16 
     | 
    
         
             
                end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
                def suppremum(other, simple_class, multi_class)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  return self if self == other
         
     | 
| 
      
 20 
     | 
    
         
            +
                  return super(other) unless other.is_a?(simple_class) or other.is_a?(multi_class)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  return super(other) unless heading.looks_similar?(other.heading)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  result_heading = heading.suppremum(other.heading)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  builder = result_heading.multi? ? multi_class : simple_class
         
     | 
| 
      
 24 
     | 
    
         
            +
                  builder.new(result_heading)
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
       18 
27 
     | 
    
         
             
                def ==(other)
         
     | 
| 
       19 
28 
     | 
    
         
             
                  super || (other.is_a?(self.class) && heading == other.heading)
         
     | 
| 
       20 
29 
     | 
    
         
             
                end
         
     | 
| 
         @@ -24,5 +33,13 @@ module Finitio 
     | 
|
| 
       24 
33 
     | 
    
         
             
                  self.class.hash ^ heading.hash
         
     | 
| 
       25 
34 
     | 
    
         
             
                end
         
     | 
| 
       26 
35 
     | 
    
         | 
| 
      
 36 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  self.class.new(heading.resolve_proxies(system), name, metadata)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 41 
     | 
    
         
            +
                  self.class.new(heading.unconstrained, name, metadata)
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
       27 
44 
     | 
    
         
             
              end # module HeadingBasedType
         
     | 
| 
       28 
45 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Finitio
         
     | 
| 
      
 2 
     | 
    
         
            +
              class HighOrderType < Type
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                def initialize(vars, defn, name = nil, metadata = nil)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  super(name, metadata)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @vars = vars
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @defn = defn
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
                attr_reader :vars, :defn
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def default_name
         
     | 
| 
      
 12 
     | 
    
         
            +
                  "Type<#{vars.join(',')}>"
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def suppremum(other)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  raise NotImplementedError, "Suppremum is not defined on high order types"
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  super || other.is_a?(HighOrderType) \
         
     | 
| 
      
 21 
     | 
    
         
            +
                        && other.vars == self.vars \
         
     | 
| 
      
 22 
     | 
    
         
            +
                        && other.defn = self.defn
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  self
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def instantiate(compilation, sub_types)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  overrides = Hash[vars.zip(sub_types)]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  defn.resolve_proxies(compilation.with_scope(overrides))
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 35 
     | 
    
         
            +
                  HighOrderType.new(vars, defn.unconstrained, name, metadata)
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              end # class HighOrderType
         
     | 
| 
      
 39 
     | 
    
         
            +
            end # module Finitio
         
     | 
| 
         @@ -11,30 +11,20 @@ module Finitio 
     | 
|
| 
       11 
11 
     | 
    
         
             
                end
         
     | 
| 
       12 
12 
     | 
    
         
             
                attr_reader :target_name, :target
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                 
     | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
       16 
     | 
    
         
            -
                  :name,
         
     | 
| 
       17 
     | 
    
         
            -
                  :name=,
         
     | 
| 
       18 
     | 
    
         
            -
                  :default_name,
         
     | 
| 
       19 
     | 
    
         
            -
                  :dress,
         
     | 
| 
       20 
     | 
    
         
            -
                  :undress,
         
     | 
| 
       21 
     | 
    
         
            -
                  :include?,
         
     | 
| 
       22 
     | 
    
         
            -
                  :==,
         
     | 
| 
       23 
     | 
    
         
            -
                  :eql?,
         
     | 
| 
       24 
     | 
    
         
            -
                  :hash,
         
     | 
| 
       25 
     | 
    
         
            -
                  :to_s
         
     | 
| 
       26 
     | 
    
         
            -
                ].each do |meth|
         
     | 
| 
       27 
     | 
    
         
            -
                  define_method(meth) do |*args, &bl|
         
     | 
| 
       28 
     | 
    
         
            -
                    raise Error, "No such type `#{@target_name}` (proxy not resolved?)" unless @target
         
     | 
| 
       29 
     | 
    
         
            -
                    @target.send(meth, *args, &bl)
         
     | 
| 
       30 
     | 
    
         
            -
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                def default_name
         
     | 
| 
      
 15 
     | 
    
         
            +
                  "_#{target_name}_"
         
     | 
| 
       31 
16 
     | 
    
         
             
                end
         
     | 
| 
       32 
17 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                def  
     | 
| 
       34 
     | 
    
         
            -
                   
     | 
| 
       35 
     | 
    
         
            -
                    raise Error, "No such type `#{target_name}`"
         
     | 
| 
      
 18 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  system.fetch(target_name){
         
     | 
| 
      
 20 
     | 
    
         
            +
                    raise Error, "No such type `#{target_name}` in #{system}"
         
     | 
| 
       36 
21 
     | 
    
         
             
                  }
         
     | 
| 
       37 
22 
     | 
    
         
             
                end
         
     | 
| 
       38 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 25 
     | 
    
         
            +
                  return @target.unconstrained if @target
         
     | 
| 
      
 26 
     | 
    
         
            +
                  raise Error, "`unconstrained` cannot be call whithout proxies being resolved"
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       39 
29 
     | 
    
         
             
              end # class ProxyType
         
     | 
| 
       40 
30 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -80,5 +80,13 @@ module Finitio 
     | 
|
| 
       80 
80 
     | 
    
         
             
                  self.class.hash ^ component_types.hash
         
     | 
| 
       81 
81 
     | 
    
         
             
                end
         
     | 
| 
       82 
82 
     | 
    
         | 
| 
      
 83 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 84 
     | 
    
         
            +
                  StructType.new(component_types.map{|t| t.resolve_proxies(system)}, name, metadata)
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 88 
     | 
    
         
            +
                  StructType.new(component_types.map{|t| t.unconstrained}, name, metadata)
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
       83 
91 
     | 
    
         
             
              end # class StructType
         
     | 
| 
       84 
92 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -81,6 +81,10 @@ module Finitio 
     | 
|
| 
       81 
81 
     | 
    
         
             
                  uped
         
     | 
| 
       82 
82 
     | 
    
         
             
                end
         
     | 
| 
       83 
83 
     | 
    
         | 
| 
      
 84 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 85 
     | 
    
         
            +
                  super_type.unconstrained
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
       84 
88 
     | 
    
         
             
                def ==(other)
         
     | 
| 
       85 
89 
     | 
    
         
             
                  super || (
         
     | 
| 
       86 
90 
     | 
    
         
             
                    other.is_a?(SubType) && (other.super_type == super_type) &&
         
     | 
| 
         @@ -93,5 +97,9 @@ module Finitio 
     | 
|
| 
       93 
97 
     | 
    
         
             
                  self.class.hash ^ super_type.hash ^ set_hash(constraints)
         
     | 
| 
       94 
98 
     | 
    
         
             
                end
         
     | 
| 
       95 
99 
     | 
    
         | 
| 
      
 100 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 101 
     | 
    
         
            +
                  SubType.new(super_type.resolve_proxies(system), constraints, name, metadata)
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
       96 
104 
     | 
    
         
             
              end # class SubType
         
     | 
| 
       97 
105 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -70,6 +70,17 @@ module Finitio 
     | 
|
| 
       70 
70 
     | 
    
         
             
                  candidates.map(&:name).join('|')
         
     | 
| 
       71 
71 
     | 
    
         
             
                end
         
     | 
| 
       72 
72 
     | 
    
         | 
| 
      
 73 
     | 
    
         
            +
                def suppremum(other)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  return self if other == self
         
     | 
| 
      
 75 
     | 
    
         
            +
                  cs = if (other.is_a?(UnionType))
         
     | 
| 
      
 76 
     | 
    
         
            +
                    candidates + other.candidates
         
     | 
| 
      
 77 
     | 
    
         
            +
                  else
         
     | 
| 
      
 78 
     | 
    
         
            +
                    candidates + [other]
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
                  UnionType.new(cs.uniq)
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
                alias :_suppremum :suppremum
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       73 
84 
     | 
    
         
             
                def ==(other)
         
     | 
| 
       74 
85 
     | 
    
         
             
                  super || (
         
     | 
| 
       75 
86 
     | 
    
         
             
                    other.is_a?(UnionType) && set_equal?(candidates, other.candidates)
         
     | 
| 
         @@ -81,5 +92,13 @@ module Finitio 
     | 
|
| 
       81 
92 
     | 
    
         
             
                  self.class.hash ^ set_hash(self.candidates)
         
     | 
| 
       82 
93 
     | 
    
         
             
                end
         
     | 
| 
       83 
94 
     | 
    
         | 
| 
      
 95 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  UnionType.new(candidates.map{|t| t.resolve_proxies(system)}, name, metadata)
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 100 
     | 
    
         
            +
                  UnionType.new(candidates.map{|c| c.unconstrained }, name, metadata)
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       84 
103 
     | 
    
         
             
              end # class UnionType
         
     | 
| 
       85 
104 
     | 
    
         
             
            end # module Finitio
         
     | 
    
        data/lib/finitio/version.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,169 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Finitio
         
     | 
| 
      
 3 
     | 
    
         
            +
              describe Generation do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                subject {
         
     | 
| 
      
 6 
     | 
    
         
            +
                  Generation.new({
         
     | 
| 
      
 7 
     | 
    
         
            +
                    :heuristic  => Generation::Heuristic::Constant.new,
         
     | 
| 
      
 8 
     | 
    
         
            +
                    :generators => generators
         
     | 
| 
      
 9 
     | 
    
         
            +
                  })
         
     | 
| 
      
 10 
     | 
    
         
            +
                }
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                let(:generators) {
         
     | 
| 
      
 13 
     | 
    
         
            +
                  {}
         
     | 
| 
      
 14 
     | 
    
         
            +
                }
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                class SubString < String
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                describe 'when called on scalar types' do
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  it 'works for nil' do
         
     | 
| 
      
 22 
     | 
    
         
            +
                    expect(subject.call(nilType)).to eql(nil)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  it 'works for ints' do
         
     | 
| 
      
 26 
     | 
    
         
            +
                    expect(subject.call(intType)).to eql(99)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  it 'works for floats' do
         
     | 
| 
      
 30 
     | 
    
         
            +
                    expect(subject.call(floatType)).to eql(99.99)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  it 'works for strings' do
         
     | 
| 
      
 34 
     | 
    
         
            +
                    expect(subject.call(stringType)).to eql("Hello world")
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  it 'works for true' do
         
     | 
| 
      
 38 
     | 
    
         
            +
                    expect(subject.call(trueType)).to be(true)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  it 'works for false' do
         
     | 
| 
      
 42 
     | 
    
         
            +
                    expect(subject.call(falseType)).to be(false)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  it 'works on ruby sub types' do
         
     | 
| 
      
 46 
     | 
    
         
            +
                    expect(subject.call(BuiltinType.new(SubString))).to eql("Hello world")
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                describe 'when called on Any type' do
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  it 'works' do
         
     | 
| 
      
 54 
     | 
    
         
            +
                    expect {
         
     | 
| 
      
 55 
     | 
    
         
            +
                      subject.call(anyType)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    }.not_to raise_error
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                describe 'when called on an alias type' do
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  it 'works' do
         
     | 
| 
      
 64 
     | 
    
         
            +
                    expect(subject.call(AliasType.new(intType, "x"))).to eql(99)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                describe 'when called on an sub type' do
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  it 'works' do
         
     | 
| 
      
 72 
     | 
    
         
            +
                    expect(subject.call(byte)).to eql(99)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                describe 'when called on a collection type' do
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  it 'works on a SeqType' do
         
     | 
| 
      
 80 
     | 
    
         
            +
                    got = subject.call(SeqType.new(intType))
         
     | 
| 
      
 81 
     | 
    
         
            +
                    expect(got).to be_a(Array)
         
     | 
| 
      
 82 
     | 
    
         
            +
                    expect(got.all?{|x| x==99 }).to be_truthy
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                  it 'works on a SetType' do
         
     | 
| 
      
 86 
     | 
    
         
            +
                    got = subject.call(SetType.new(intType))
         
     | 
| 
      
 87 
     | 
    
         
            +
                    expect(got).to be_a(Array)
         
     | 
| 
      
 88 
     | 
    
         
            +
                    expect(got.all?{|x| x==99 }).to be_truthy
         
     | 
| 
      
 89 
     | 
    
         
            +
                  end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                describe 'when called on tuple types' do
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                  it 'works as expected' do
         
     | 
| 
      
 96 
     | 
    
         
            +
                    type = TupleType.new(Heading.new [Attribute.new(:i, intType)])
         
     | 
| 
      
 97 
     | 
    
         
            +
                    expect(subject.call(type)).to eql({i: 99})
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  it 'works as expected' do
         
     | 
| 
      
 101 
     | 
    
         
            +
                    type = MultiTupleType.new(Heading.new [Attribute.new(:i, intType)])
         
     | 
| 
      
 102 
     | 
    
         
            +
                    expect(subject.call(type)).to eql({i: 99})
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                describe 'when called on relation types' do
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  it 'works as expected' do
         
     | 
| 
      
 110 
     | 
    
         
            +
                    type = RelationType.new(Heading.new [Attribute.new(:i, intType)])
         
     | 
| 
      
 111 
     | 
    
         
            +
                    expect(subject.call(type)).to eql([{i: 99}])
         
     | 
| 
      
 112 
     | 
    
         
            +
                  end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                  it 'works as expected' do
         
     | 
| 
      
 115 
     | 
    
         
            +
                    type = MultiRelationType.new(Heading.new [Attribute.new(:i, intType)])
         
     | 
| 
      
 116 
     | 
    
         
            +
                    expect(subject.call(type)).to eql([{i: 99}])
         
     | 
| 
      
 117 
     | 
    
         
            +
                  end
         
     | 
| 
      
 118 
     | 
    
         
            +
                end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                describe 'when called on a union type' do
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                  it 'works as expected' do
         
     | 
| 
      
 123 
     | 
    
         
            +
                    type = UnionType.new([trueType, falseType])
         
     | 
| 
      
 124 
     | 
    
         
            +
                    expect([true, false].include? subject.call(type)).to be_truthy
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                describe 'when called on an AD type' do
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                  it 'works' do
         
     | 
| 
      
 132 
     | 
    
         
            +
                    type = AdType.new(Color, [rgb_contract])
         
     | 
| 
      
 133 
     | 
    
         
            +
                    expect(subject.call(byte)).to eql(99)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                describe 'when examples are provided in metadata' do
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                  it 'takes the priority' do
         
     | 
| 
      
 141 
     | 
    
         
            +
                    type = AliasType.new(intType, "X", { examples: [97] })
         
     | 
| 
      
 142 
     | 
    
         
            +
                    expect(subject.call(type)).to eql(97)
         
     | 
| 
      
 143 
     | 
    
         
            +
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                describe 'when a generator exists' do
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                  let(:generators) {
         
     | 
| 
      
 150 
     | 
    
         
            +
                    {
         
     | 
| 
      
 151 
     | 
    
         
            +
                      "X" => ->(type, gen, _) { 96 },
         
     | 
| 
      
 152 
     | 
    
         
            +
                      "Y" => ->(type, gen, world) { world }
         
     | 
| 
      
 153 
     | 
    
         
            +
                    }
         
     | 
| 
      
 154 
     | 
    
         
            +
                  }
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                  it 'takes the priority even over examples' do
         
     | 
| 
      
 157 
     | 
    
         
            +
                    type = AliasType.new(intType, "X", { examples: [97] })
         
     | 
| 
      
 158 
     | 
    
         
            +
                    expect(subject.call(type)).to eql(96)
         
     | 
| 
      
 159 
     | 
    
         
            +
                  end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                  it 'lets pass a world' do
         
     | 
| 
      
 162 
     | 
    
         
            +
                    type = AliasType.new(intType, "Y", { examples: [97] })
         
     | 
| 
      
 163 
     | 
    
         
            +
                    expect(subject.call(type, 17)).to eql(17)
         
     | 
| 
      
 164 
     | 
    
         
            +
                  end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
              end
         
     | 
| 
      
 169 
     | 
    
         
            +
            end
         
     |