Class: ActiveFacts::Metamodel::Reading

Inherits:
Object
  • Object
show all
Defined in:
lib/activefacts/vocabulary/metamodel.rb,
lib/activefacts/vocabulary/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)



500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
# File 'lib/activefacts/vocabulary/extensions.rb', line 500

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
      # REVISIT: hyphenated trailing adjectives are not correctly represented here
      t_adj = "#{role_ref.trailing_adjective}".sub(/(\b.|\A.)/, '-\1').sub(/ -/,'  -')
      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
  #debug "Expanded '#{expanded}' using #{frequency_constraints.inspect}"
  expanded
end

#expand_with_final_presence_constraint(&b) ⇒ Object



576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
# File 'lib/activefacts/vocabulary/extensions.rb', line 576

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



572
573
574
# File 'lib/activefacts/vocabulary/extensions.rb', line 572

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

#words_and_role_refsObject



558
559
560
561
562
563
564
565
566
567
568
569
# File 'lib/activefacts/vocabulary/extensions.rb', line 558

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