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,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Finitio
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Inference
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                def initialize(system, options = {})
         
     | 
| 
      
 5 
     | 
    
         
            +
                  @system = system
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @options = options
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :system
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def call(input)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  infer_type(input)
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              private
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def infer_type(value)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  case value
         
     | 
| 
      
 18 
     | 
    
         
            +
                  when Hash
         
     | 
| 
      
 19 
     | 
    
         
            +
                    attrs = value.map{|k,v|
         
     | 
| 
      
 20 
     | 
    
         
            +
                      Attribute.new(k.to_sym, infer_type(v))
         
     | 
| 
      
 21 
     | 
    
         
            +
                    }
         
     | 
| 
      
 22 
     | 
    
         
            +
                    heading = Heading.new(attrs)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    TupleType.new(heading)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  when Array
         
     | 
| 
      
 25 
     | 
    
         
            +
                    infered = value.inject(nil){|sup, value|
         
     | 
| 
      
 26 
     | 
    
         
            +
                      value_type = infer_type(value)
         
     | 
| 
      
 27 
     | 
    
         
            +
                      sup.nil? ? value_type : sup.suppremum(value_type)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    }
         
     | 
| 
      
 29 
     | 
    
         
            +
                    SeqType.new(infered.nil? ? ANY_TYPE : infered)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  else
         
     | 
| 
      
 31 
     | 
    
         
            +
                    found = self.system.types.values.find{|t|
         
     | 
| 
      
 32 
     | 
    
         
            +
                      try_dress(t, value)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    }
         
     | 
| 
      
 34 
     | 
    
         
            +
                    found ? found : ANY_TYPE
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                def try_dress(t, value)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  raise "Type expected, got #{t}" unless t.is_a?(Type)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  t.dress(value)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  true
         
     | 
| 
      
 42 
     | 
    
         
            +
                rescue Finitio::Error => ex
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #puts %Q{[#{ex.class}] #{ex.message}}
         
     | 
| 
      
 44 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 45 
     | 
    
         
            +
                rescue => ex
         
     | 
| 
      
 46 
     | 
    
         
            +
                  puts %Q{[#{ex.class}] #{ex.message}\n#{ex.backtrace.join("\n")}}
         
     | 
| 
      
 47 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              end # class Inference
         
     | 
| 
      
 51 
     | 
    
         
            +
            end # module Finitio
         
     | 
    
        data/lib/finitio/support.rb
    CHANGED
    
    | 
         @@ -1,3 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Finitio
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Support
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                def compare_attrs(h1, h2, &bl)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  mine, yours = if bl
         
     | 
| 
      
 6 
     | 
    
         
            +
                    [h1.map(&bl), h2.map(&bl)]
         
     | 
| 
      
 7 
     | 
    
         
            +
                  elsif h1.is_a?(Hash)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    [h1.keys, h2.keys]
         
     | 
| 
      
 9 
     | 
    
         
            +
                  else
         
     | 
| 
      
 10 
     | 
    
         
            +
                    [h1, h2]
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  [ mine & yours, mine - yours, yours - mine ]
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
                module_function :compare_attrs
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              end # module Support
         
     | 
| 
      
 17 
     | 
    
         
            +
            end # module Finitio
         
     | 
| 
       1 
18 
     | 
    
         
             
            require_relative 'support/proc_with_code'
         
     | 
| 
       2 
19 
     | 
    
         
             
            require_relative 'support/metadata'
         
     | 
| 
       3 
20 
     | 
    
         
             
            require_relative 'support/attribute'
         
     | 
| 
         @@ -6,4 +23,5 @@ require_relative 'support/contract' 
     | 
|
| 
       6 
23 
     | 
    
         
             
            require_relative 'support/heading'
         
     | 
| 
       7 
24 
     | 
    
         
             
            require_relative 'support/dress_helper'
         
     | 
| 
       8 
25 
     | 
    
         
             
            require_relative 'support/type_factory'
         
     | 
| 
      
 26 
     | 
    
         
            +
            require_relative 'support/fetch_scope'
         
     | 
| 
       9 
27 
     | 
    
         
             
            require_relative 'support/compilation'
         
     | 
| 
         @@ -55,5 +55,13 @@ module Finitio 
     | 
|
| 
       55 
55 
     | 
    
         
             
                  name.hash ^ type.hash ^ required.hash
         
     | 
| 
       56 
56 
     | 
    
         
             
                end
         
     | 
| 
       57 
57 
     | 
    
         | 
| 
      
 58 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  Attribute.new(name, type.resolve_proxies(system), required, metadata)
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 63 
     | 
    
         
            +
                  Attribute.new(name, type.unconstrained, required, metadata)
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
       58 
66 
     | 
    
         
             
              end # class Attribute
         
     | 
| 
       59 
67 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -1,19 +1,19 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Finitio
         
     | 
| 
       2 
2 
     | 
    
         
             
              class Compilation
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
                def initialize(system = System.new, factory = TypeFactory.new, source = nil)
         
     | 
| 
      
 4 
     | 
    
         
            +
                def initialize(system = System.new, factory = TypeFactory.new, scope = nil, source = nil)
         
     | 
| 
       5 
5 
     | 
    
         
             
                  @system  = system
         
     | 
| 
       6 
6 
     | 
    
         
             
                  @factory = factory
         
     | 
| 
       7 
     | 
    
         
            -
                  @ 
     | 
| 
      
 7 
     | 
    
         
            +
                  @scope = scope || FetchScope.new(system, {})
         
     | 
| 
       8 
8 
     | 
    
         
             
                  @source = source
         
     | 
| 
       9 
9 
     | 
    
         
             
                end
         
     | 
| 
       10 
     | 
    
         
            -
                attr_reader :system, :factory, : 
     | 
| 
      
 10 
     | 
    
         
            +
                attr_reader :system, :factory, :scope, :source
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                def self.coerce(arg, source = nil)
         
     | 
| 
       13 
13 
     | 
    
         
             
                  case arg
         
     | 
| 
       14 
     | 
    
         
            -
                  when NilClass    then new(System.new, TypeFactory.new, source)
         
     | 
| 
       15 
     | 
    
         
            -
                  when System      then new(arg, arg.factory, source)
         
     | 
| 
       16 
     | 
    
         
            -
                  when TypeFactory then new(System.new, arg, source)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  when NilClass    then new(System.new, TypeFactory.new, nil, source)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  when System      then new(arg, arg.factory, nil, source)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  when TypeFactory then new(System.new, arg, nil, source)
         
     | 
| 
       17 
17 
     | 
    
         
             
                  else
         
     | 
| 
       18 
18 
     | 
    
         
             
                    raise ArgumentError, "Unable to coerce `#{arg}`"
         
     | 
| 
       19 
19 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -48,11 +48,8 @@ module Finitio 
     | 
|
| 
       48 
48 
     | 
    
         
             
                  Pathname.new(file)
         
     | 
| 
       49 
49 
     | 
    
         
             
                end
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                def resolve_proxies 
     | 
| 
       52 
     | 
    
         
            -
                   
     | 
| 
       53 
     | 
    
         
            -
                    p.resolve(system)
         
     | 
| 
       54 
     | 
    
         
            -
                  end
         
     | 
| 
       55 
     | 
    
         
            -
                  self
         
     | 
| 
      
 51 
     | 
    
         
            +
                def resolve_proxies
         
     | 
| 
      
 52 
     | 
    
         
            +
                  system.resolve_proxies
         
     | 
| 
       56 
53 
     | 
    
         
             
                end
         
     | 
| 
       57 
54 
     | 
    
         | 
| 
       58 
55 
     | 
    
         
             
                # Delegation to Factory
         
     | 
| 
         @@ -63,17 +60,10 @@ module Finitio 
     | 
|
| 
       63 
60 
     | 
    
         
             
                  }
         
     | 
| 
       64 
61 
     | 
    
         
             
                end
         
     | 
| 
       65 
62 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
                def proxy(*args, &bl)
         
     | 
| 
       67 
     | 
    
         
            -
                  proxy = factory.proxy(*args, &bl)
         
     | 
| 
       68 
     | 
    
         
            -
                  proxies << proxy
         
     | 
| 
       69 
     | 
    
         
            -
                  proxy
         
     | 
| 
       70 
     | 
    
         
            -
                end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
63 
     | 
    
         
             
                # Delegation to System
         
     | 
| 
       73 
64 
     | 
    
         | 
| 
       74 
65 
     | 
    
         
             
                [
         
     | 
| 
       75 
66 
     | 
    
         
             
                  :add_type,
         
     | 
| 
       76 
     | 
    
         
            -
                  :fetch,
         
     | 
| 
       77 
67 
     | 
    
         
             
                  :main,
         
     | 
| 
       78 
68 
     | 
    
         
             
                ].each do |meth|
         
     | 
| 
       79 
69 
     | 
    
         
             
                  define_method(meth) do |*args, &bl|
         
     | 
| 
         @@ -81,5 +71,15 @@ module Finitio 
     | 
|
| 
       81 
71 
     | 
    
         
             
                  end
         
     | 
| 
       82 
72 
     | 
    
         
             
                end
         
     | 
| 
       83 
73 
     | 
    
         | 
| 
      
 74 
     | 
    
         
            +
                # Delegation to FetchScope
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                def fetch(type_name, &bl)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  scope.fetch(type_name, &bl)
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def with_scope(overrides)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  Compilation.new(system, factory, scope.with(overrides), source)
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       84 
84 
     | 
    
         
             
              end # class Compilation
         
     | 
| 
       85 
85 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -44,5 +44,13 @@ module Finitio 
     | 
|
| 
       44 
44 
     | 
    
         
             
                end
         
     | 
| 
       45 
45 
     | 
    
         
             
                alias :eql? :==
         
     | 
| 
       46 
46 
     | 
    
         | 
| 
      
 47 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  Contract.new(infotype.resolve_proxies(system), dresser, undresser, name, metadata)
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 52 
     | 
    
         
            +
                  Contract.new(infotype.unconstrained, dresser, undresser, name, metadata)
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
       47 
55 
     | 
    
         
             
              end # class Contract
         
     | 
| 
       48 
56 
     | 
    
         
             
            end # module Finitio
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Finitio
         
     | 
| 
      
 2 
     | 
    
         
            +
              class FetchScope
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                def initialize(parent, overrides)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  @parent, @overrides = parent, overrides
         
     | 
| 
      
 6 
     | 
    
         
            +
                end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def fetch(name, &bl)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @overrides.fetch(name) do
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @parent.fetch(name, &bl)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def with(overrides)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  FetchScope.new(self, overrides)
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              end # class FetchScope
         
     | 
| 
      
 19 
     | 
    
         
            +
            end # module Finitio
         
     | 
| 
         @@ -61,6 +61,32 @@ module Finitio 
     | 
|
| 
       61 
61 
     | 
    
         
             
                  name
         
     | 
| 
       62 
62 
     | 
    
         
             
                end
         
     | 
| 
       63 
63 
     | 
    
         | 
| 
      
 64 
     | 
    
         
            +
                def looks_similar?(other)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  return self if other == self
         
     | 
| 
      
 66 
     | 
    
         
            +
                  shared, mine, yours = Support.compare_attrs(attributes, other.attributes)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  shared.length >= mine.length && shared.length >= yours.length
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                def suppremum(other)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  raise ArgumentError unless other.is_a?(Heading)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  return self if other == self
         
     | 
| 
      
 73 
     | 
    
         
            +
                  options = { allow_extra: allow_extra? || other.allow_extra? }
         
     | 
| 
      
 74 
     | 
    
         
            +
                  shared, mine, yours = Support.compare_attrs(attributes, other.attributes)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  attributes = shared.map{|attr|
         
     | 
| 
      
 76 
     | 
    
         
            +
                    a1, o1 = self[attr], other[attr]
         
     | 
| 
      
 77 
     | 
    
         
            +
                    Attribute.new(attr, a1.type.suppremum(o1.type), a1.required && o1.required)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  }
         
     | 
| 
      
 79 
     | 
    
         
            +
                  attributes += mine.map{|attrname|
         
     | 
| 
      
 80 
     | 
    
         
            +
                    attr = self[attrname]
         
     | 
| 
      
 81 
     | 
    
         
            +
                    Attribute.new(attr.name, attr.type, false)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  }
         
     | 
| 
      
 83 
     | 
    
         
            +
                  attributes += yours.map{|attrname|
         
     | 
| 
      
 84 
     | 
    
         
            +
                    attr = other[attrname]
         
     | 
| 
      
 85 
     | 
    
         
            +
                    Attribute.new(attr.name, attr.type, false)
         
     | 
| 
      
 86 
     | 
    
         
            +
                  }
         
     | 
| 
      
 87 
     | 
    
         
            +
                  Heading.new(attributes, options)
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
       64 
90 
     | 
    
         
             
                def ==(other)
         
     | 
| 
       65 
91 
     | 
    
         
             
                  return nil unless other.is_a?(Heading)
         
     | 
| 
       66 
92 
     | 
    
         
             
                  attributes == other.attributes && options == other.options
         
     | 
| 
         @@ -73,6 +99,15 @@ module Finitio 
     | 
|
| 
       73 
99 
     | 
    
         
             
                attr_reader :attributes, :options
         
     | 
| 
       74 
100 
     | 
    
         
             
                protected   :attributes, :options
         
     | 
| 
       75 
101 
     | 
    
         | 
| 
      
 102 
     | 
    
         
            +
                def resolve_proxies(system)
         
     | 
| 
      
 103 
     | 
    
         
            +
                  as = attributes.map{|k,a| a.resolve_proxies(system) }
         
     | 
| 
      
 104 
     | 
    
         
            +
                  Heading.new(as, options)
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                def unconstrained
         
     | 
| 
      
 108 
     | 
    
         
            +
                  Heading.new(attributes.values.map{|a| a.unconstrained }, options)
         
     | 
| 
      
 109 
     | 
    
         
            +
                end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
       76 
111 
     | 
    
         
             
              private
         
     | 
| 
       77 
112 
     | 
    
         | 
| 
       78 
113 
     | 
    
         
             
                def normalize_attributes(attrs)
         
     | 
| 
         @@ -83,7 +118,7 @@ module Finitio 
     | 
|
| 
       83 
118 
     | 
    
         
             
                  attributes = {}
         
     | 
| 
       84 
119 
     | 
    
         
             
                  attrs.each do |attr|
         
     | 
| 
       85 
120 
     | 
    
         
             
                    unless attr.is_a?(Attribute)
         
     | 
| 
       86 
     | 
    
         
            -
                      raise ArgumentError, "Enumerable[Attribute] expected"
         
     | 
| 
      
 121 
     | 
    
         
            +
                      raise ArgumentError, "Enumerable[Attribute] expected, got a `#{attr.inspect}`"
         
     | 
| 
       87 
122 
     | 
    
         
             
                    end
         
     | 
| 
       88 
123 
     | 
    
         
             
                    if attributes[attr.name]
         
     | 
| 
       89 
124 
     | 
    
         
             
                      raise ArgumentError, "Attribute names must be unique"
         
     | 
    
        data/lib/finitio/syntax.rb
    CHANGED
    
    
    
        data/lib/finitio/syntax/type.rb
    CHANGED
    
    | 
         @@ -19,9 +19,11 @@ require_relative 'type/relation_type' 
     | 
|
| 
       19 
19 
     | 
    
         
             
            require_relative 'type/union_type'
         
     | 
| 
       20 
20 
     | 
    
         
             
            require_relative 'type/type_ref'
         
     | 
| 
       21 
21 
     | 
    
         
             
            require_relative 'type/ad_type'
         
     | 
| 
      
 22 
     | 
    
         
            +
            require_relative 'type/high_order_type_instantiation'
         
     | 
| 
       22 
23 
     | 
    
         
             
            require_relative 'type/contract'
         
     | 
| 
       23 
24 
     | 
    
         
             
            require_relative 'type/inline_pair'
         
     | 
| 
       24 
25 
     | 
    
         
             
            require_relative 'type/external_pair'
         
     | 
| 
       25 
26 
     | 
    
         
             
            require_relative 'type/lambda_expr'
         
     | 
| 
       26 
27 
     | 
    
         
             
            require_relative 'type/metadata'
         
     | 
| 
       27 
28 
     | 
    
         
             
            require_relative 'type/metadata_attr'
         
     | 
| 
      
 29 
     | 
    
         
            +
            require_relative 'type/high_order_vars'
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Finitio
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Syntax
         
     | 
| 
      
 3 
     | 
    
         
            +
                module HighOrderTypeInstantiation
         
     | 
| 
      
 4 
     | 
    
         
            +
                  include Node
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  capture :high
         
     | 
| 
      
 7 
     | 
    
         
            +
                  capture :vars
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def compile(system)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    target = system.fetch(high.to_s){
         
     | 
| 
      
 11 
     | 
    
         
            +
                      raise Error, "No such type `#{high.to_s}`"
         
     | 
| 
      
 12 
     | 
    
         
            +
                    }
         
     | 
| 
      
 13 
     | 
    
         
            +
                    raise "#{high} is not a high order type" unless target.is_a?(HighOrderType)
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    subs = vars.compile(system).map{|low|
         
     | 
| 
      
 16 
     | 
    
         
            +
                      system.fetch(low.to_s) {
         
     | 
| 
      
 17 
     | 
    
         
            +
                        raise Error, "No such type `#{low.to_s}`"
         
     | 
| 
      
 18 
     | 
    
         
            +
                      }
         
     | 
| 
      
 19 
     | 
    
         
            +
                    }
         
     | 
| 
      
 20 
     | 
    
         
            +
                    target.instantiate(system, subs)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  def to_ast
         
     | 
| 
      
 24 
     | 
    
         
            +
                    [:high_order_type_instantiation, high.to_s, lows.to_s]
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                end # module HighOrderTypeInstantiation
         
     | 
| 
      
 28 
     | 
    
         
            +
              end # module Syntax
         
     | 
| 
      
 29 
     | 
    
         
            +
            end # module Finitio
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Finitio
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Syntax
         
     | 
| 
      
 3 
     | 
    
         
            +
                module HighOrderVars
         
     | 
| 
      
 4 
     | 
    
         
            +
                  include Node
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  def compile(system)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    captures[:type_name].map{|c| c.to_s }
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def to_ast(var_name)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    [ :high_order_vars, captures[:type_name].map{|c| c.to_s } ]
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                end # module HighOrderVars
         
     | 
| 
      
 15 
     | 
    
         
            +
              end # module Syntax
         
     | 
| 
      
 16 
     | 
    
         
            +
            end # module Finitio
         
     | 
| 
         @@ -5,9 +5,19 @@ module Finitio 
     | 
|
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
                  capture :type
         
     | 
| 
       7 
7 
     | 
    
         
             
                  capture :type_name
         
     | 
| 
      
 8 
     | 
    
         
            +
                  capture :vars
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
10 
     | 
    
         
             
                  def compile(system)
         
     | 
| 
       10 
     | 
    
         
            -
                     
     | 
| 
      
 11 
     | 
    
         
            +
                    if vars
         
     | 
| 
      
 12 
     | 
    
         
            +
                      vs = vars.compile(system)
         
     | 
| 
      
 13 
     | 
    
         
            +
                      overrides = Hash[vs.map{|v|
         
     | 
| 
      
 14 
     | 
    
         
            +
                        [ v.to_s, ProxyType.new(v) ]
         
     | 
| 
      
 15 
     | 
    
         
            +
                      }]
         
     | 
| 
      
 16 
     | 
    
         
            +
                      t = type.compile(system.with_scope(overrides))
         
     | 
| 
      
 17 
     | 
    
         
            +
                      t = HighOrderType.new(vs, t)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    else
         
     | 
| 
      
 19 
     | 
    
         
            +
                      t = type.compile(system)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
       11 
21 
     | 
    
         
             
                    n = type_name && type_name.to_str
         
     | 
| 
       12 
22 
     | 
    
         
             
                    m = metadata
         
     | 
| 
       13 
23 
     | 
    
         
             
                    system.add_type(t, n, m)
         
     | 
| 
         @@ -6,10 +6,15 @@ grammar Finitio::Syntax::Types 
     | 
|
| 
       6 
6 
     | 
    
         
             
              include Finitio::Syntax::Literals
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
              rule type_def
         
     | 
| 
       9 
     | 
    
         
            -
                (metadata? type_name equal type)
         
     | 
| 
      
 9 
     | 
    
         
            +
                (metadata? type_name ('<' vars:high_order_vars '>')? equal type)
         
     | 
| 
       10 
10 
     | 
    
         
             
                <Finitio::Syntax::TypeDef>
         
     | 
| 
       11 
11 
     | 
    
         
             
              end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
      
 13 
     | 
    
         
            +
              rule high_order_vars
         
     | 
| 
      
 14 
     | 
    
         
            +
                (type_name (comma type_name)*)
         
     | 
| 
      
 15 
     | 
    
         
            +
                <Finitio::Syntax::HighOrderVars>
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       13 
18 
     | 
    
         
             
              rule main_type
         
     | 
| 
       14 
19 
     | 
    
         
             
                (metadata? type)
         
     | 
| 
       15 
20 
     | 
    
         
             
                <Finitio::Syntax::MainType>
         
     | 
| 
         @@ -58,6 +63,7 @@ grammar Finitio::Syntax::Types 
     | 
|
| 
       58 
63 
     | 
    
         
             
              rule rel_type
         
     | 
| 
       59 
64 
     | 
    
         
             
                  relation_type
         
     | 
| 
       60 
65 
     | 
    
         
             
                | tuple_type
         
     | 
| 
      
 66 
     | 
    
         
            +
                | high_order_type_instantiation
         
     | 
| 
       61 
67 
     | 
    
         
             
                | collection_type
         
     | 
| 
       62 
68 
     | 
    
         
             
              end
         
     | 
| 
       63 
69 
     | 
    
         | 
| 
         @@ -110,6 +116,13 @@ grammar Finitio::Syntax::Types 
     | 
|
| 
       110 
116 
     | 
    
         
             
                <Finitio::Syntax::StructType>
         
     | 
| 
       111 
117 
     | 
    
         
             
              end
         
     | 
| 
       112 
118 
     | 
    
         | 
| 
      
 119 
     | 
    
         
            +
              # high-order types
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
              rule high_order_type_instantiation
         
     | 
| 
      
 122 
     | 
    
         
            +
                (high:type_name '<' vars:high_order_vars '>')
         
     | 
| 
      
 123 
     | 
    
         
            +
                <Finitio::Syntax::HighOrderTypeInstantiation>
         
     | 
| 
      
 124 
     | 
    
         
            +
              end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
       113 
126 
     | 
    
         
             
              # terminal forms
         
     | 
| 
       114 
127 
     | 
    
         | 
| 
       115 
128 
     | 
    
         
             
              rule term_type
         
     | 
    
        data/lib/finitio/system.rb
    CHANGED
    
    | 
         @@ -10,7 +10,7 @@ module Finitio 
     | 
|
| 
       10 
10 
     | 
    
         
             
                end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                attr_reader :types, :imports
         
     | 
| 
       13 
     | 
    
         
            -
                private : 
     | 
| 
      
 13 
     | 
    
         
            +
                private :imports
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                def add_import(system)
         
     | 
| 
       16 
16 
     | 
    
         
             
                  @imports << system
         
     | 
| 
         @@ -89,6 +89,16 @@ module Finitio 
     | 
|
| 
       89 
89 
     | 
    
         
             
                  Syntax.compile(source, self.dup)
         
     | 
| 
       90 
90 
     | 
    
         
             
                end
         
     | 
| 
       91 
91 
     | 
    
         | 
| 
      
 92 
     | 
    
         
            +
                def resolve_proxies(recurse = true)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  rebuilt = {}
         
     | 
| 
      
 94 
     | 
    
         
            +
                  scope = FetchScope.new(self, rebuilt)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  types.each_with_object(rebuilt) do |(name,type),memo|
         
     | 
| 
      
 96 
     | 
    
         
            +
                    rebuilt[name] = type.resolve_proxies(scope)
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
                  resolved = System.new(rebuilt, imports)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  recurse ? resolved.resolve_proxies(false) : resolved
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
       92 
102 
     | 
    
         
             
                def inspect
         
     | 
| 
       93 
103 
     | 
    
         
             
                  @types.each_pair.map{|k,v| "#{k} = #{v}" }.join("\n")
         
     | 
| 
       94 
104 
     | 
    
         
             
                end
         
     |