private HashSet <State> InitialStates(ExpressionsList expressions)
        {
            var             allStates     = PossibleStates(expressions);
            HashSet <State> initialStates = new HashSet <State>();

            if (expressions.Initially.Count == 0)
            {
                initialStates = allStates;
            }
            else
            {
                var initialConditions = expressions.Initially
                                        .Select(x => x.Condition)
                                        .Aggregate((a, b) => new And(a, b))
                                        .EvaluateLogicExpression();

                foreach (var state in allStates)
                {
                    if (initialConditions.Any(x => state.Values.HasSubset(x)))
                    {
                        initialStates.Add(state);
                    }
                }
            }

            return(initialStates);
        }
        private Dictionary <Triple, HashSet <State> > Res(ExpressionsList expressions)
        {
            var results = new Dictionary <Triple, HashSet <State> >();
            var res0    = Res0(expressions);
            var temp    = res0.GroupBy(x => x.Key);

            foreach (var key in res0.Keys)
            {
                var state          = key.Item2;
                var action         = key.Item1;
                var agents         = key.Item3;
                var newBasedOnRes0 = res0[key].Select(x => New(expressions, state, x, agents, action)).ToList();
                foreach (var te in res0[key])
                {
                    var t = New(expressions, state, te, agents, action);
                }
                if (newBasedOnRes0.Count != 0)
                {
                    //should be minimal with respect to set inclusions.
                    var min = newBasedOnRes0.Min(x => x.Count); //res0[key].Select(x => New(expressions, state, x, agents, action).Count).Min();
                    //var temp2 = res0[key].Select(x => New(expressions, state, x, agents, action));
                    var res = res0[key].Where(x => New(expressions, state, x, agents, action).Count == min);
                    results.Add(key, new HashSet <State>(res));
                }
            }

            return(results);
        }
        public HashSet <State> PossibleStates(ExpressionsList expressions)
        {
            HashSet <State> result = new HashSet <State>();
            //get all fluents
            var fluents = expressions.Fluents;

            //with brute force method create every possible combination of 0 and 1 fluents
            for (int i = 0; i < Math.Pow(2, fluents.Count); i++)
            {
                var binary = Convert.ToString(i, 2).PadLeft(fluents.Count, '0').Select(x => x == '1' ? true : false).ToArray();
                Dictionary <string, bool> stateValues = new Dictionary <string, bool>();
                for (int j = 0; j < fluents.Count; j++)
                {
                    stateValues[fluents[j]] = binary[j];
                }
                result.Add(new State(stateValues));
            }
            //now if there is at least one always statement cut impossible states
            if (expressions.Always.Count != 0)
            {
                //get all always statements, then get conditions
                var always = expressions.Always.Select(x => x.Condition)
                             //aggregate them to one uber-always condition and finally evaluate logic expression
                             .Aggregate((a, b) => new And(a, b)).EvaluateLogicExpression();
                //if state is compliant to the always logic expression then add it to the set
                result = new HashSet <State>(result.Where(s => always.Any(a => a.Intersect(s.Values).Count() == a.Count())));
            }
            return(result);
        }
        public void Test0_2()
        {
            string story       = @"
Fluent R1
Fluent R2
Fluent R3
Agent g1
Agent g2
Agent g3
Agent g4
Action A1
Action A2
A1 by [g1, g2, g3] causes [R1]
A1 by [g1, g3] causes [R3]
A2 by [g2, g3, g4] causes [R2]
A2 by [g1, g4] causes [R2]
";
            var    tokens      = Tokenizer.Tokenize(story);
            var    parserState = Parser.Parse(tokens);
            var    expressions = new ExpressionsList();

            expressions.AddRange(parserState.Expression);
            expressions.AddRange(parserState.Noninertial.Values);

            string query = @"
possibly [g2] engaged in (A1, [g1, g2, g3]),(A2, [g2, g3, g4])
";

            Query q = Parser.ParseQuery(Tokenizer.Tokenize(query), parserState);

            var res = q.Solve(expressions);

            Assert.AreEqual(true, res);
        }
        public void Test1()
        {
            string story       = @"
Fluent hasA
Fluent hasB
Agent g
Action buypaper
buypaper by [g] causes [hasA || hasB]
";
            var    tokens      = Tokenizer.Tokenize(story);
            var    parserState = Parser.Parse(tokens);
            var    expressions = new ExpressionsList();

            expressions.AddRange(parserState.Expression);
            expressions.AddRange(parserState.Noninertial.Values);

            string query = @"
possibly [g] engaged in (buypaper, [g])
";

            Query q = Parser.ParseQuery(
                Tokenizer.Tokenize(query),
                parserState);

            var result = q.Solve(expressions);

            Assert.IsTrue(result);
        }
        public override bool Solve(ExpressionsList expressions)
        {
            var reasoningEngine = new ReasoningEngine();
            var structure       = reasoningEngine.GenerateStructure(expressions);
            var res             = structure.Res;
            var initialStates   = structure.InitialStates;
            var allStates       = structure.PossibleStates;
            var piCondition     = Condition.EvaluateLogicExpression();

            //we want that list to hold result of query for each initial state
            //could be done prettier but it's easier to read
            List <bool> resultsForEachInitiallState = new List <bool>();

            //for each initiall state
            foreach (var initialState in initialStates)
            {
                HashSet <State> currentStates = new HashSet <State>();
                //if condition is always true then our current state is initial state
                if (Condition.Element is True)
                {
                    currentStates.Add(initialState);
                }
                //else we have to find all states that are ok
                else
                {
                    foreach (var state in allStates)
                    {
                        if (piCondition.Any(x => state.Values.HasSubset(x)))
                        {
                            currentStates.Add(state);
                        }
                    }
                }
                //now we iterate through instructions
                for (int i = 0; i < Instructions.Count; i++)
                {
                    var             action           = Instructions[i].Item1;
                    var             agents           = Instructions[i].Item2;
                    HashSet <State> newCurrentStates = new HashSet <State>();
                    //for each state in current states we want to move forward in graph
                    foreach (var currentState in currentStates)
                    {
                        var triple = new Triple(action, currentState, agents);
                        //if we can find good edge in graph
                        //from currentState, specific action and agents group then
                        if (res.ContainsKey(triple))
                        {
                            //add all next states to the newCurrentStates
                            res[triple].ToList().ForEach(s => newCurrentStates.Add(s));
                        }
                    }
                    //do it again for new action and agents group
                    currentStates = newCurrentStates;
                }
                resultsForEachInitiallState.Add(currentStates.Count != 0);
            }
            return(resultsForEachInitiallState.All(x => x));
        }
        private HashSet <string> New(ExpressionsList expressions, State from, State to, AgentsList agents, Action action)
        {
            //find all fluents that differs
            var diff = to.Values.Where(x => !from.Values.Contains(x)).Select(x => x.Key);

            //except noninertial ones
            diff = diff.Except(expressions.Noninertial.Select(x => x.Fluent.Name));
            //add fluents from release statements
            diff = diff.Concat(expressions.Releases.Where(
                                   x => x.Action.Equals(action) &&
                                   agents.HasSubset(x.Agents) &&
                                   x.Condition.EvaluateLogicExpression().Any(e => from.Values.HasSubset(e))).Select(x => x.Fluent.Name));

            return(new HashSet <string>(diff));
            //maybe except should be at the end of the query?
        }
 private List <string> InertialFluents(ExpressionsList expressions)
 {
     return(expressions.Fluents.Except(expressions.Noninertial.Select(x => x.Fluent.Name)).ToList());
 }
        private Dictionary <Triple, HashSet <State> > Res0(ExpressionsList expressions)
        {
            Dictionary <Triple, HashSet <State> > result = new Dictionary <Triple, HashSet <State> >();

            //For each group of Cause statements e.g.
            //A causes alpha if pi
            //A causes beta
            //we want to group them together, so that we can examine them wrt to state and agents group
            foreach (var action in expressions.Actions)
            {
                var causesGroup = expressions.Causes.Where(x => x.A.Equals(action));
                //for each state in possible states
                foreach (var state in PossibleStates(expressions))
                {
                    //for each group in possible agents group
                    foreach (var group in expressions.AgentsGroups())
                    {
                        //we want to create list of cause statements that works with specific state and agent group
                        List <ByCausesIf> workingCauses = new List <ByCausesIf>();
                        List <bool>       piConditions  = new List <bool>();
                        //now we iterate through the cause statements to find those
                        foreach (var cause in causesGroup)
                        {
                            var w1 = cause.Pi.EvaluateLogicExpression().Any(x => state.Values.HasSubset(x));
                            piConditions.Add(w1);
                            var w2 = group.HasSubset(cause.G);
                            var w3 = cause.Alpha.EvaluateLogicExpression().Count != 0;
                            //if pi condition is ok with current state
                            if (cause.Pi.EvaluateLogicExpression().Any(x => state.Values.HasSubset(x))
                                //if group is superset
                                && group.HasSubset(cause.G))
                            //if alpha condition is not false
                            //&& cause.Alpha.EvaluateLogicExpression().Count != 0)
                            {
                                //then we add new cause expression
                                workingCauses.Add(cause);
                            }
                        }
                        //create our A x sigma x G triple
                        Triple tuple = new Triple(
                            action, state, group);
                        if (workingCauses.Count == 0)
                        {
                            if (piConditions.All(x => !x))
                            {
                                result.Add(tuple, PossibleStates(expressions));
                            }
                            continue;
                        }
                        //now we need to create uber-alpha condition
                        var uberAlpha = workingCauses.Select(x => x.Alpha).Aggregate((a, b) => new And(a, b));
                        //final states should be compliant with our uberAlpha
                        var final = uberAlpha.EvaluateLogicExpression();
                        //look through all possible states to find the ones that can end this action, and create set
                        var setOfFinalStates = new HashSet <State>();
                        foreach (var s in PossibleStates(expressions))
                        {
                            //if state s is compliant then add it to the set
                            if (final.Any(x => s.Values.HasSubset(x)))
                            {
                                setOfFinalStates.Add(s);
                            }
                        }
                        //add triple and set to dictionary
                        if (result.ContainsKey(tuple))
                        {
                            setOfFinalStates.ToList().ForEach(x => result[tuple].Add(x));
                        }
                        else
                        {
                            result.Add(tuple, setOfFinalStates);
                        }
                    }
                }
            }
            return(result);
        }
        public Structure GenerateStructure(ExpressionsList expressions)
        {
            var res            = Res(expressions);
            var possibleStates = PossibleStates(expressions);
            var initialStates  = InitialStates(expressions);

            var resWithAfter = new Dictionary <Triple, HashSet <State> >();

            #region After statements
            //now lets get to the part where we intersect
            //initial states with after statements
            var afterExpressions = expressions.AfterExpressions;
            if (afterExpressions.Count != 0)
            {
                foreach (var after in afterExpressions)
                {
                    Dictionary <Triple, HashSet <State> > changesInRes = new Dictionary <Triple, HashSet <State> >();
                    HashSet <State> currentStates = new HashSet <State>();
                    //find final states
                    foreach (var state in possibleStates)
                    {
                        if (after.FinalCondition.EvaluateLogicExpression().Any(x => state.Values.HasSubset(x)))
                        {
                            currentStates.Add(state);
                        }
                    }
                    //we are going backward
                    after.Instructions.Reverse();
                    //now we iterate through instructions
                    for (int i = 0; i < after.Instructions.Count; i++)
                    {
                        var             action           = after.Instructions[i].Item1;
                        var             agents           = after.Instructions[i].Item2;
                        HashSet <State> newCurrentStates = new HashSet <State>();
                        //for each state in current states we want to move backward in graph
                        //we have action name, agents group and final state of edge
                        foreach (var currentState in currentStates)
                        {
                            var previousStates = res.Where(kv => kv.Value.Contains(currentState) &&
                                                           kv.Key.Item1.Equals(action) &&
                                                           kv.Key.Item3.Equals(agents)).ToList();

                            foreach (var kv in previousStates)
                            {
                                if (!resWithAfter.ContainsKey(kv.Key))
                                {
                                    var a = res[kv.Key];
                                    resWithAfter[kv.Key] = new HashSet <State>();
                                }
                                resWithAfter[kv.Key].Add(currentState);
                                newCurrentStates.Add(kv.Key.Item2);
                            }
                        }

                        currentStates = newCurrentStates;
                    }
                    //now we must get only initial states that are possible
                    initialStates.IntersectWith(currentStates);
                }
                foreach (var kv in resWithAfter)
                {
                    res[kv.Key].Clear();
                    res[kv.Key] = kv.Value;
                }
            }
            #endregion

            #region Observable After statements
            var observableAfterExpressions = expressions.ObservableAfterExpressions;
            if (observableAfterExpressions.Count != 0)
            {
                foreach (var observableAfter in observableAfterExpressions)
                {
                    HashSet <State> currentStates = new HashSet <State>();
                    //find final states
                    foreach (var state in possibleStates)
                    {
                        if (observableAfter.FinalCondition.EvaluateLogicExpression().Any(x => state.Values.HasSubset(x)))
                        {
                            currentStates.Add(state);
                        }
                    }
                    //we are going backward
                    observableAfter.Instructions.Reverse();
                    //now we iterate through instructions
                    for (int i = 0; i < observableAfter.Instructions.Count; i++)
                    {
                        var             action           = observableAfter.Instructions[i].Item1;
                        var             agents           = observableAfter.Instructions[i].Item2;
                        HashSet <State> newCurrentStates = new HashSet <State>();
                        //for each state in current states we want to move backward in graph
                        //we have action name, agents group and final state of edge
                        foreach (var currentState in currentStates)
                        {
                            foreach (var kv in res)
                            {
                                if (kv.Value.Contains(currentState) &&
                                    kv.Key.Item1.Equals(action) &&
                                    kv.Key.Item3.Equals(agents))
                                {
                                    newCurrentStates.Add(kv.Key.Item2);
                                }
                            }
                        }
                        currentStates = newCurrentStates;
                    }
                    //observable after expression really does nothing, except when there are not any path - then the whole model is false -> don't have any initial nodes
                    if (currentStates.Count == 0)
                    {
                        initialStates = new HashSet <State>();
                    }
                }
            }
            #endregion

            return(new Structure(initialStates, possibleStates, res));
        }
Esempio n. 11
0
 public abstract bool Solve(ExpressionsList expressions);