Module: ActiveFacts::Metamodel
- Defined in:
- lib/activefacts/persistence/index.rb,
lib/activefacts/persistence/tables.rb,
lib/activefacts/persistence/columns.rb,
lib/activefacts/vocabulary/metamodel.rb,
lib/activefacts/persistence/reference.rb,
lib/activefacts/vocabulary/extensions.rb,
lib/activefacts/vocabulary/verbaliser.rb,
lib/activefacts/persistence/foreignkey.rb
Overview
:nodoc:
Defined Under Namespace
Classes: Adjective, Agent, AgentName, Agreement, AllowedRange, Assimilation, Bound, Coefficient, Concept, Constraint, ConstraintId, ConstraintShape, ContextAccordingTo, ContextAgreedBy, ContextNote, ContextNoteId, ContextNoteKind, Date, Denominator, Derivation, Diagram, Discussion, DisplayRoleNamesSetting, Enforcement, EnforcementCode, EntityType, EphemeraURL, Exponent, Fact, FactId, FactType, FactTypeId, FactTypeShape, Frequency, ImplicitBooleanValueType, ImplicitFactType, Instance, InstanceId, Join, JoinId, JoinNode, JoinRole, JoinStep, Length, Literal, ModelNoteShape, Name, Numerator, ObjectTypeShape, ObjectifiedFactTypeNameShape, Offset, Ordinal, ParamValue, Parameter, Population, Position, PresenceConstraint, Pronoun, Reading, ReadingShape, RingConstraint, RingConstraintShape, RingType, Role, RoleDisplay, RoleNameShape, RoleRef, RoleSequence, RoleSequenceId, RoleValue, RotationSetting, Scale, SetComparisonConstraint, SetComparisonRoles, SetConstraint, SetEqualityConstraint, SetExclusionConstraint, Shape, ShapeId, Subscript, SubsetConstraint, Text, TypeInheritance, Unit, UnitId, Value, ValueConstraint, ValueConstraintShape, ValueRange, ValueType, Verbaliser, Vocabulary, X, Y
Class Method Summary collapse
-
.join_roles_over(roles, options = :both) ⇒ Object
Some joins must be over the proximate roles, some over the counterpart roles.
Class Method Details
.join_roles_over(roles, options = :both) ⇒ Object
Some joins must be over the proximate roles, some over the counterpart roles. Return the common superclass of the appropriate roles, and the actual roles
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 |
# File 'lib/activefacts/vocabulary/extensions.rb', line 690 def self.join_roles_over roles, = :both # Or :proximate, :counterpart # If we can stay inside this objectified FT, there's no join: roles = Array(roles) # To be safe, in case we get a role collection proxy return nil if roles.size == 1 or != :counterpart && roles.map{|role| role.fact_type}.uniq.size == 1 proximate_sups, counterpart_sups, obj_sups, counterpart_roles, objectification_roles = *roles.inject(nil) do |d_c_o, role| concept = role.concept fact_type = role.fact_type proximate_role_supertypes = concept.supertypes_transitive # A role in an objectified fact type may indicate either the objectification or the counterpart player. # This could be ambiguous. Figure out both and prefer the counterpart over the objectification. counterpart_role_supertypes = if fact_type.all_role.size > 2 possible_roles = fact_type.all_role.select{|r| d_c_o && d_c_o[1].include?(r.concept) } if possible_roles.size == 1 # Only one candidate matches the types of the possible join nodes counterpart_role = possible_roles[0] d_c_o[1] # No change else # puts "#{constraint_type} #{name}: Awkward, try counterpart-role join on a >2ary '#{fact_type.default_reading}'" # Try all roles; hopefully we don't have two roles with a matching candidate here: # Find which role is compatible with the existing supertypes, if any if d_c_o st = nil counterpart_role = fact_type.all_role.detect{|r| ((st = r.concept.supertypes_transitive) & d_c_o[1]).size > 0} st else counterpart_role = nil # This can't work, we don't have any basis for a decision (must be objectification) [] end #fact_type.all_role.map{|r| r.concept.supertypes_transitive}.flatten.uniq end else # Get the supertypes of the counterpart role (care with unaries): ftr = role.fact_type.all_role.to_a (counterpart_role = ftr[0] == role ? ftr[-1] : ftr[0]).concept.supertypes_transitive end if fact_type.entity_type objectification_role_supertypes = fact_type.entity_type.supertypes_transitive+concept.supertypes_transitive objectification_role = role.implicit_fact_type.all_role.single # Find the phantom role here else objectification_role_supertypes = counterpart_role_supertypes objectification_role = counterpart_role end if !d_c_o d_c_o = [proximate_role_supertypes, counterpart_role_supertypes, objectification_role_supertypes, [counterpart_role], [objectification_role]] #puts "role player supertypes starts #{d_c_o.map{|dco| dco.map(&:name).inspect}*' or '}" else #puts "continues #{[proximate_role_supertypes, counterpart_role_supertypes, objectification_role_supertypes]map{|dco| dco.map(&:name).inspect}*' or '}" d_c_o[0] &= proximate_role_supertypes d_c_o[1] &= counterpart_role_supertypes d_c_o[2] &= objectification_role_supertypes d_c_o[3] << (counterpart_role || objectification_role) d_c_o[4] << (objectification_role || counterpart_role) end d_c_o end # inject # Discount a subtype join over an object type that's not a player here, # if we can use an objectification join to an object type that is: if counterpart_sups.size > 0 && obj_sups.size > 0 && counterpart_sups[0] != obj_sups[0] debug :join, "ambiguous join, could be over #{counterpart_sups[0].name} or #{obj_sups[0].name}" if !roles.detect{|r| r.concept == counterpart_sups[0]} and roles.detect{|r| r.concept == obj_sups[0]} debug :join, "discounting #{counterpart_sups[0].name} in favour of direct objectification" counterpart_sups = [] end end # Choose the first entry in the first non-empty supertypes list: if != :counterpart && proximate_sups[0] [ proximate_sups[0], roles ] elsif !counterpart_sups.empty? [ counterpart_sups[0], counterpart_roles ] else [ obj_sups[0], objectification_roles ] end end |