/// <summary> /// Instantiates a new atom group. /// </summary> /// <param name="logicalOperator">The operator that characterizes the relationship between the atoms and atoms group.</param> /// <param name="members">An array containing atoms and atom groups.</param> /// <param name="runningMembers">An array containing atoms and atom groups that will actually be run (they can be different /// from the members because of atom equivalence).</param> internal AtomGroup(LogicalOperator logicalOperator, object[] members, object[] runningMembers) { this.logicalOperator = logicalOperator; this.members = members; HashCodeBuilder hcb = new HashCodeBuilder(); hcb.Append(logicalOperator); SortedList<int, object> sortedMembers = new SortedList<int, object>(Comparer<int>.Default); // check the members, compute hashcode and build sorted members list for(int i=0; i < members.Length; i++) { object member =members[i]; if (member == null) { throw new BREException("An atom group can not contain a null member"); } else if (member is AtomGroup) { if (((AtomGroup)member).logicalOperator == logicalOperator) throw new BREException("An atom group can not contain another group with the same logical operator"); } else if (member is Atom) { if (((Atom)member).HasFormula) throw new BREException("An atom group can not contain an atom that contains a formula"); } else { throw new BREException("An atom group can not hold objects of type: " + member.GetType()); } hcb.Append(member); if (runningMembers == null) sortedMembers.Add(GetMemberSortedIndex(members, i), member); } hashCode = hcb.Value; // the members actually used when processing the atom group are not the ones defined in the rule file (usually because of equivalent atoms definitions) if (runningMembers != null) { for(int i=0; i < runningMembers.Length; i++) sortedMembers.Add(GetMemberSortedIndex(runningMembers, i), runningMembers[i]); } orderedMembers = sortedMembers.Values; allAtoms = new List<Atom>(); foreach(object member in orderedMembers) { if (member is Atom) allAtoms.Add((Atom)member); else if (member is AtomGroup) allAtoms.AddRange(((AtomGroup)member).AllAtoms); } }
/// <summary> /// Instantiates a new function predicate. /// </summary> /// <param name="resolutionType">The type of resolution for the function.</param> /// <param name="predicate">The predicate value, i.e. the string representation of the function predicate.</param> /// <param name="bob">The business object binder to use when evaluating the function, or null.</param> /// <param name="name">The name of the function, as it was analyzed by the binder.</param> /// <param name="arguments">The array of arguments of the function, as it was analyzed by the binder.</param> public Function(FunctionResolutionType resolutionType, string predicate, IBinder bob, string name, params string[] arguments) : base(predicate) { this.resolutionType = resolutionType; this.bob = bob; this.name = name; this.arguments = arguments; HashCodeBuilder hcb = new HashCodeBuilder(base.GetHashCode()).Append(resolutionType).Append(bob).Append(name); foreach(string argument in arguments) hcb.Append(argument); hashCode = hcb.Value; // precalculate the function signature to use in the binder to evaluate the function functionSignature = Parameter.BuildFunctionSignature(name, arguments); }
/// <summary> /// Instantiates a new Atom. /// </summary> /// <param name="negative">Negative Atom.</param> /// <param name="type">The relation type of the Atom.</param> /// <param name="members">Array of predicates associated in the Atom.</param> /// <remarks>This is the principal constructor for Atom and descendant objects.</remarks> public Atom(bool negative, string type, params IPredicate[] members) { this.negative = negative; this.type = type; // load the predicates, extracting the slot names if any predicates = new IPredicate[members.Length]; slotNames = new string[members.Length]; hasSlot = false; for(int i=0; i<members.Length; i++) { if (members[i] is Slot) { hasSlot = true; Slot slot = (Slot)members[i]; predicates[i] = slot.Predicate; slotNames[i] = slot.Name; } else { predicates[i] = members[i]; slotNames[i] = String.Empty; } } // initialize long hashcode & other characteristics HashCodeBuilder hcb = new HashCodeBuilder().Append(type); isFact = true; hasFunction = false; hasFormula = false; hasIndividual = false; onlyVariables = true; foreach(IPredicate member in predicates) { hcb.Append(member); if (member is Individual) hasIndividual = true; else isFact = false; if (!(member is Variable)) onlyVariables = false; if (member is Function) hasFunction = true; else if (member is Formula) hasFormula = true; } hashCode = hcb.Value; // initialize signature signature = type + predicates.Length; }