Class: ActiveFacts::Metamodel::Reading

Inherits:
Object
  • Object
show all
Defined in:
lib/activefacts/metamodel/metamodel.rb,
lib/activefacts/metamodel/extensions.rb

Instance Method Summary collapse

Instance Method Details

#expand(frequency_constraints = [], define_role_names = nil, literals = [], &subscript_block) ⇒ Object

The frequency_constraints array here, if supplied, may provide for each role either:

  • a PresenceConstraint to be verbalised against the relevant role, or

  • a String, used as a definite or indefinite article on the relevant role, or

  • an array containing two strings (an article and a super-type name)

The order in the array is the same as the reading’s role-sequence. REVISIT: This should probably be changed to be the fact role sequence.

define_role_names here is false (use defined names), true (define names) or nil (neither)



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
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
# File 'lib/activefacts/metamodel/extensions.rb', line 963

def expand(frequency_constraints = [], define_role_names = nil, literals = [], &subscript_block)
  expanded = "#{text}"
  role_refs = role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
  (0...role_refs.size).each{|i|
      role_ref = role_refs[i]
      role = role_ref.role
      l_adj = "#{role_ref.leading_adjective}".sub(/(\b-\b|.\b|.\Z)/, '\1-').sub(/\b--\b/,'-- ').sub(/- /,'-  ')
      l_adj = nil if l_adj == ""
      # Double the space to compensate for space removed below
      t_adj = "#{role_ref.trailing_adjective}".sub(/\w+$/,' -\0').sub(/--\w*$/, ' \0')
      t_adj = nil if t_adj == ""

      expanded.gsub!(/\{#{i}\}/) do
          role_ref = role_refs[i]
          if role_ref.role
            player = role_ref.role.object_type
            role_name = role.role_name
            role_name = nil if role_name == ""
            if role_name && define_role_names == false
              l_adj = t_adj = nil   # When using role names, don't add adjectives
            end

            freq_con = frequency_constraints[i]
            freq_con = freq_con.frequency if freq_con && freq_con.is_a?(ActiveFacts::Metamodel::PresenceConstraint)
            if freq_con.is_a?(Array)
              freq_con, player_name = *freq_con
            else
              player_name = player.name
            end
          else
            # We have an unknown role. The reading cannot be correctly expanded
            player_name = "UNKNOWN"
            role_name = nil
            freq_con = nil
          end

          literal = literals[i]
          words = [
            freq_con ? freq_con : nil,
            l_adj,
            define_role_names == false && role_name ? role_name : player_name,
            t_adj,
            define_role_names && role_name && player_name != role_name ? "(as #{role_name})" : nil,
            # Can't have both a literal and a value constraint, but we don't enforce that here:
            literal ? literal : nil
          ]
          if (subscript_block)
            words = subscript_block.call(role_ref, *words)
          end
          words.compact*" "
      end
  }
  expanded.gsub!(/ ?- ?/, '-')        # Remove single spaces around adjectives
  #trace "Expanded '#{expanded}' using #{frequency_constraints.inspect}"
  expanded
end

#expand_with_final_presence_constraint(&b) ⇒ Object



1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
# File 'lib/activefacts/metamodel/extensions.rb', line 1038

def expand_with_final_presence_constraint &b
  # Arrange the roles in order they occur in this reading:
  role_refs = role_sequence.all_role_ref_in_order
  role_numbers = text.scan(/\{(\d)\}/).flatten.map{|m| Integer(m) }
  roles = role_numbers.map{|m| role_refs[m].role }
  fact_constraints = fact_type.internal_presence_constraints

  # Find the constraints that constrain frequency over each role we can verbalise:
  frequency_constraints = []
  roles.each do |role|
    frequency_constraints <<
      if (role == roles.last)   # On the last role of the reading, emit any presence constraint
        constraint = fact_constraints.
          detect do |c|  # Find a UC that spans all other Roles
            c.is_a?(ActiveFacts::Metamodel::PresenceConstraint) &&
              roles-c.role_sequence.all_role_ref.map(&:role) == [role]
          end
        constraint && constraint.frequency
      else
        nil
      end
  end

  expand(frequency_constraints) { |*a| b && b.call(*a) }
end

#role_numbersObject

Return the array of the numbers of the RoleRefs inserted into this reading from the role_sequence



1034
1035
1036
# File 'lib/activefacts/metamodel/extensions.rb', line 1034

def role_numbers
  text.scan(/\{(\d)\}/).flatten.map{|m| Integer(m) }
end

#words_and_role_refsObject



1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
# File 'lib/activefacts/metamodel/extensions.rb', line 1020

def words_and_role_refs
  text.
  scan(/(?: |\{[0-9]+\}|[^{} ]+)/).   # split up the text into words
  reject{|s| s==' '}.                 # Remove white space
  map do |frag|                       # and go through the bits
    if frag =~ /\{([0-9]+)\}/
      role_sequence.all_role_ref.detect{|rr| rr.ordinal == $1.to_i}
    else
      frag
    end
  end
end