Class: ActiveFacts::CQL::Compiler::Reference
- Inherits:
-
Object
- Object
- ActiveFacts::CQL::Compiler::Reference
- Defined in:
- lib/activefacts/cql/compiler/clause.rb
Instance Attribute Summary collapse
-
#binding ⇒ Object
What Binding for that ObjectType.
-
#clause ⇒ Object
The clause that this Reference is part of.
-
#embedded_presence_constraint ⇒ Object
readonly
This refers to the ActiveFacts::Metamodel::PresenceConstraint.
-
#function_call ⇒ Object
readonly
Returns the value of attribute function_call.
-
#leading_adjective ⇒ Object
Returns the value of attribute leading_adjective.
-
#literal ⇒ Object
readonly
Returns the value of attribute literal.
-
#nested_clauses ⇒ Object
readonly
Returns the value of attribute nested_clauses.
-
#objectification_of ⇒ Object
If nested_clauses is set, this is the fact type it objectifies.
-
#player ⇒ Object
What ObjectType does the Binding denote.
-
#quantifier ⇒ Object
readonly
Returns the value of attribute quantifier.
-
#role ⇒ Object
Which Role of this ObjectType.
-
#role_name ⇒ Object
Returns the value of attribute role_name.
-
#role_ref ⇒ Object
Which RoleRef to that Role.
-
#term ⇒ Object
readonly
Returns the value of attribute term.
-
#trailing_adjective ⇒ Object
Returns the value of attribute trailing_adjective.
-
#value_constraint ⇒ Object
readonly
Returns the value of attribute value_constraint.
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #bind(context) ⇒ Object
- #find_pc_over_roles(roles) ⇒ Object
- #identify_other_players(context) ⇒ Object
- #identify_player(context) ⇒ Object
- #identify_players_with_role_name(context) ⇒ Object
- #includes_literals ⇒ Object
-
#initialize(term, leading_adjective = nil, trailing_adjective = nil, quantifier = nil, function_call = nil, role_name = nil, value_constraint = nil, literal = nil, nested_clauses = nil) ⇒ Reference
constructor
A new instance of Reference.
- #inspect ⇒ Object
- #key ⇒ Object
- #make_embedded_presence_constraint(vocabulary) ⇒ Object
- #rebind(context) ⇒ Object
- #rebind_to(context, other_ref) ⇒ Object
- #result(context = nil) ⇒ Object
- #to_s ⇒ Object
- #unbind(context) ⇒ Object
- #uses_role_name? ⇒ Boolean
-
#wipe_leading_adjective ⇒ Object
These are called when we successfully match a fact type reading that has relevant adjectives:.
- #wipe_trailing_adjective ⇒ Object
Constructor Details
#initialize(term, leading_adjective = nil, trailing_adjective = nil, quantifier = nil, function_call = nil, role_name = nil, value_constraint = nil, literal = nil, nested_clauses = nil) ⇒ Reference
Returns a new instance of Reference.
873 874 875 876 877 878 879 880 881 882 883 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 873 def initialize term, leading_adjective = nil, trailing_adjective = nil, quantifier = nil, function_call = nil, role_name = nil, value_constraint = nil, literal = nil, nested_clauses = nil @term = term @leading_adjective = leading_adjective @trailing_adjective = trailing_adjective @quantifier = quantifier # @function_call = function_call # Not used or implemented @role_name = role_name @value_constraint = value_constraint @literal = literal @nested_clauses = nested_clauses end |
Instance Attribute Details
#binding ⇒ Object
What Binding for that ObjectType
866 867 868 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 866 def binding @binding end |
#clause ⇒ Object
The clause that this Reference is part of
869 870 871 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 869 def clause @clause end |
#embedded_presence_constraint ⇒ Object (readonly)
This refers to the ActiveFacts::Metamodel::PresenceConstraint
871 872 873 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 871 def @embedded_presence_constraint end |
#function_call ⇒ Object (readonly)
Returns the value of attribute function_call.
863 864 865 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 863 def function_call @function_call end |
#leading_adjective ⇒ Object
Returns the value of attribute leading_adjective.
864 865 866 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 864 def leading_adjective @leading_adjective end |
#literal ⇒ Object (readonly)
Returns the value of attribute literal.
863 864 865 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 863 def literal @literal end |
#nested_clauses ⇒ Object (readonly)
Returns the value of attribute nested_clauses.
863 864 865 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 863 def nested_clauses @nested_clauses end |
#objectification_of ⇒ Object
If nested_clauses is set, this is the fact type it objectifies
870 871 872 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 870 def objectification_of @objectification_of end |
#player ⇒ Object
What ObjectType does the Binding denote
865 866 867 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 865 def player @player end |
#quantifier ⇒ Object (readonly)
Returns the value of attribute quantifier.
863 864 865 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 863 def quantifier @quantifier end |
#role ⇒ Object
Which Role of this ObjectType
867 868 869 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 867 def role @role end |
#role_name ⇒ Object
Returns the value of attribute role_name.
864 865 866 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 864 def role_name @role_name end |
#role_ref ⇒ Object
Which RoleRef to that Role
868 869 870 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 868 def role_ref @role_ref end |
#term ⇒ Object (readonly)
Returns the value of attribute term.
863 864 865 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 863 def term @term end |
#trailing_adjective ⇒ Object
Returns the value of attribute trailing_adjective.
864 865 866 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 864 def trailing_adjective @trailing_adjective end |
#value_constraint ⇒ Object (readonly)
Returns the value of attribute value_constraint.
863 864 865 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 863 def value_constraint @value_constraint end |
Instance Method Details
#<=>(other) ⇒ Object
907 908 909 910 911 912 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 907 def <=>(other) ( 4*(@term <=> other.term) + 2*((@leading_adjective||'') <=> (other.leading_adjective||'')) + 1*((@trailing_adjective||'') <=> (other.trailing_adjective||'')) ) <=> 0 end |
#bind(context) ⇒ Object
960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 960 def bind context @nested_clauses.each{|c| c.bind context} if @nested_clauses if role_name = @role_name # Omit these tests to see if anything evil eventuates: #if @leading_adjective || @trailing_adjective # raise "Role reference may not have adjectives if it defines a role name or uses a subscript: #{inspect}" #end else if uses_role_name? if @leading_adjective || @trailing_adjective raise "Role reference may not have adjectives if it uses a role name: #{inspect}" end role_name = @term end end k = key @binding = context.bindings[k] if !@binding if !literal # Find a binding that has a literal, and bind to it if it's the only one candidates = context.bindings.map do |binding_key, binding| binding_key[0...k.size] == k && binding_key[-2] == :literal ? binding : nil end.compact raise "Uncertain binding reference for #{to_s}, could be any of #{candidates.inspect}" if candidates.size > 1 @binding = candidates[0] else # New binding has a literal, look for one without: @binding = context.bindings[k[0...-2]] end end if !@binding @binding = Binding.new(@player, role_name) context.bindings[k] = @binding end @binding.add_ref self @binding end |
#find_pc_over_roles(roles) ⇒ Object
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 1038 def find_pc_over_roles(roles) return nil if roles.size == 0 # Safeguard; this would chuck an exception otherwise roles[0].all_role_ref.each do |role_ref| next if role_ref.role_sequence.all_role_ref.map(&:role) != roles pc = role_ref.role_sequence.all_presence_constraint.single # Will return nil if there's more than one. #puts "Existing PresenceConstraint matches those roles!" if pc return pc if pc end nil end |
#identify_other_players(context) ⇒ Object
929 930 931 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 929 def identify_other_players context identify_player context end |
#identify_player(context) ⇒ Object
933 934 935 936 937 938 939 940 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 933 def identify_player context @player || begin @player = context.object_type @term raise "ObjectType #{@term} unrecognised" unless @player context.player_by_role_name[@role_name] = player if @role_name @player end end |
#identify_players_with_role_name(context) ⇒ Object
923 924 925 926 927 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 923 def identify_players_with_role_name(context) identify_player(context) if role_name # Include players in nested clauses, if any nested_clauses.each{|clause| clause.identify_players_with_role_name(context)} if nested_clauses end |
#includes_literals ⇒ Object
914 915 916 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 914 def includes_literals @nested_clauses && @nested_clauses.detect{|nested| nested.includes_literals} end |
#inspect ⇒ Object
885 886 887 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 885 def inspect to_s end |
#key ⇒ Object
946 947 948 949 950 951 952 953 954 955 956 957 958 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 946 def key if @role_name key = [@term, @role_name] # Defines a role name elsif uses_role_name? key = [@player.name, @term] # Uses a role name else l = @leading_adjective t = @trailing_adjective key = [!l || l.empty? ? nil : l, @term, !t || t.empty? ? nil : t] end key += [:literal, literal.literal] if @literal key end |
#make_embedded_presence_constraint(vocabulary) ⇒ Object
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 1049 def vocabulary raise "No Role for embedded_presence_constraint" unless @role_ref fact_type = @role_ref.role.fact_type constellation = vocabulary.constellation trace :constraint, "Processing embedded constraint #{@quantifier.inspect} on #{@role_ref.role.object_type.name} in #{fact_type.describe}" do # Preserve the role order of the clause, excluding this role: constrained_roles = (@clause.refs-[self]).map{|vr| vr.role_ref.role} if constrained_roles.empty? trace :constraint, "Quantifier over unary role has no effect" return end constraint = find_pc_over_roles(constrained_roles) if constraint raise "Conflicting maximum frequency for constraint" if constraint.max_frequency && constraint.max_frequency != @quantifier.max trace :constraint, "Setting max frequency to #{@quantifier.max} for existing constraint #{constraint.object_id} over #{constraint.role_sequence.describe} in #{fact_type.describe}" unless constraint.max_frequency constraint.max_frequency = @quantifier.max raise "Conflicting minimum frequency for constraint" if constraint.min_frequency && constraint.min_frequency != @quantifier.min trace :constraint, "Setting min frequency to #{@quantifier.min} for existing constraint #{constraint.object_id} over #{constraint.role_sequence.describe} in #{fact_type.describe}" unless constraint.min_frequency constraint.min_frequency = @quantifier.min else role_sequence = constellation.RoleSequence(:new) constrained_roles.each_with_index do |constrained_role, i| role_ref = constellation.RoleRef(role_sequence, i, :role => constrained_role) end constraint = constellation.PresenceConstraint( :new, :vocabulary => vocabulary, :role_sequence => role_sequence, :is_mandatory => @quantifier.min && @quantifier.min > 0, # REVISIT: Check "maybe" qualifier? :max_frequency => @quantifier.max, :min_frequency => @quantifier.min ) if @quantifier.pragmas @quantifier.pragmas.each do |p| constellation.ConceptAnnotation(:concept => constraint.concept, :mapping_annotation => p) end end trace :constraint, "Made new embedded PC GUID=#{constraint.concept.guid} min=#{@quantifier.min.inspect} max=#{@quantifier.max.inspect} over #{(e = fact_type.entity_type) ? e.name : role_sequence.describe} in #{fact_type.describe}" @quantifier.enforcement.compile(constellation, constraint) if @quantifier.enforcement @embedded_presence_constraint = constraint end constraint end end |
#rebind(context) ⇒ Object
1010 1011 1012 1013 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 1010 def rebind(context) unbind context bind context end |
#rebind_to(context, other_ref) ⇒ Object
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 1015 def rebind_to(context, other_ref) trace :binding, "Rebinding #{inspect} to #{other_ref.inspect}" old_binding = binding # Remember to move all refs across unbind(context) new_binding = other_ref.binding [self, *old_binding.refs].each do |ref| ref.binding = new_binding new_binding.add_ref ref end old_binding.rebound_to = new_binding end |
#result(context = nil) ⇒ Object
1096 1097 1098 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 1096 def result(context = nil) self end |
#to_s ⇒ Object
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 889 def to_s "{#{ @quantifier && @quantifier.inspect+' ' }#{ @leading_adjective && @leading_adjective.sub(/ |$/,'- ').sub(/ *$/,' ') }#{ @term }#{ @trailing_adjective && ' '+@trailing_adjective.sub(/(.* |^)/, '\1-') }#{ @role_name and @role_name.is_a?(Integer) ? "(#{@role_name})" : " (as #{@role_name})" }#{ @literal && ' '+@literal.inspect }#{ @value_constraint && ' '+@value_constraint.to_s }}" end |
#unbind(context) ⇒ Object
1000 1001 1002 1003 1004 1005 1006 1007 1008 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 1000 def unbind context # The key has changed. @binding.delete_ref self if @binding.refs.empty? # Remove the binding from the context if this was the last reference context.bindings.delete_if {|k,v| v == @binding } end @binding = nil end |
#uses_role_name? ⇒ Boolean
942 943 944 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 942 def uses_role_name? @term != @player.name end |
#wipe_leading_adjective ⇒ Object
These are called when we successfully match a fact type reading that has relevant adjectives:
1030 1031 1032 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 1030 def wipe_leading_adjective @leading_adjective = nil end |
#wipe_trailing_adjective ⇒ Object
1034 1035 1036 |
# File 'lib/activefacts/cql/compiler/clause.rb', line 1034 def wipe_trailing_adjective @trailing_adjective = nil end |