Exemplo n.º 1
0
        public void Apply(HashSet <Fact> facts, HashSet <Fact> newFacts, HashSet <ulong> restrictedSymbols)
        {
            HashSet <ulong> variablesSet = new HashSet <ulong>();

            foreach (Predicate pred in this.Body)
            {
                variablesSet.AddAll(pred.Ids.Where(id => id is ID.Variable).Select(id => ((ID.Variable)id).Value));
            }
            MatchedVariables variables = new MatchedVariables(variablesSet);

            if (!this.Body.Any())
            {
                Option <Dictionary <ulong, ID> > h_opt = variables.CheckExpressions(this.Expressions);
                if (h_opt.IsDefined)
                {
                    Dictionary <ulong, ID> h = h_opt.Get();
                    Predicate predicate      = this.Head.Clone();

                    for (int i = 0; i < predicate.Ids.Count; i++)
                    {
                        ID id = predicate.Ids[i];
                        if (id is ID.Variable)
                        {
                            ID value = h[((ID.Variable)id).Value];
                            predicate.Ids[i] = value;
                        }
                    }

                    newFacts.Add(new Fact(predicate));
                }
            }

            var combined = new Combinator(variables, this.Body, this.Expressions, facts).Combine();

            foreach (Dictionary <ulong, ID> h in combined)
            {
                Predicate predicate        = this.Head.Clone();
                bool      unbound_variable = false;

                for (int i = 0; i < predicate.Ids.Count; i++)
                {
                    ID id = predicate.Ids[i];
                    if (id is ID.Variable)
                    {
                        bool isInDictionnary = h.TryGetValue(((ID.Variable)id).Value, out ID value);

                        predicate.Ids[i] = value;
                        // variables that appear in the head should appear in the body and constraints as well
                        if (value == null)
                        {
                            unbound_variable = true;
                        }
                    }
                }
                // if the generated fact has #authority or #ambient as first element and we're n ot in a privileged rule
                // do not generate it
                bool isRestrictedSymbol = false;
                ID   first = predicate.Ids.FirstOrDefault();
                if (first != null && first is ID.Symbol)
                {
                    if (restrictedSymbols.Contains(((ID.Symbol)first).Value))
                    {
                        isRestrictedSymbol = true;
                    }
                }
                if (!unbound_variable && !isRestrictedSymbol)
                {
                    newFacts.Add(new Fact(predicate));
                }
            }
        }