* Checks whether adding p to this node would violate cardinality constraints
  * @param p OntProperty
  * @return true if adding the property would violate a cardinality constraint
 public boolean violatesCardinality(OntProperty p) {
   if (p.isInverseFunctionalProperty()) {
     if (node.getIncomingEdges(p.getLocalName()).size() > 0) return true;
   OntProperty inverse = reader.getInverse(p);
   if (inverse == null)
     return false; // if the inverse property does not exist there are no cardinal constraints on
   // it...
   if (optional.contains(inverse) || compulsory.contains(inverse)) return false;
   if (addShowOrHideOption() == SGNode.INCOMPLETE) return false;
   return true;
   * Initialises the anchor, finding the node's compulsory and optional properties and their NL
   * representations and ordering it all in lists and maps, using the submenus.
   * @param c OntClass corresponding to this anchor
   * @param query true if this is an anchor for a node in the QueryGraph
   * @throws BadAnchorException if the given SGNode does not need an anchor
  public void init(OntClass c, boolean query) throws BadAnchorException {
    Map<String, Integer[]> map = reader.getCardinalities(c.getLocalName());
    List<OntProperty> list = reader.getDomainProperties(c.getLocalName());
    for (int i = 0; i < list.size(); i++) {
      OntProperty p = list.get(i);
      String name = p.getLocalName();
      int nr =
          node.getOutgoingEdges(name).size(); // number of times the node already has this property
      String inverse = reader.getInverse(name); // , n.getLabel(), null);
      if (inverse != null)
        nr +=
                .size(); // plus the number of times the inverse has this node as range

      if (map.containsKey(name)) {
        int min =
            map.get(name)[0]; // if the minimum cardinality is not satisfied, add to 'compulsory'
        int max = map.get(name)[1];
        if (query) optional.add(p); // for the query, cardinality constraints do not matter
        else if ((min != 0)
            && (min > nr)) // if the minimum cardinality > 0, add the property to compulsory
        else if ((max == 0)
            || (max > nr)) // if the maximum cardinality will not be violated, add to optional
      } else optional.add(p); // no cardinality constraints, so add to optional

    if (!compulsory.isEmpty()) // if there are compulsory properties, this is a red anchor
    redAnchor = true;
    else if (optional.isEmpty()) // compulsory and optional both empty - means this is not an anchor
    throw new BadAnchorException(
          "Node " + node.getLabel() + " is not an anchor anymore; all its relations are specified");