示例#1
0
        private Graph MergeBind(Bind rightBind, BindState rightState)
        {
            //HORRORS BELOW
            var x = this;

            var leftBinds = rightState.Nodes
                            .Select(n => x.NodeBinds.TryGetValue(n, out var found) ? found : null)
                            .Where(n => n != null)
                            .ToArray();

            var leftStates = leftBinds
                             .SelectMany(b => x.BindStates.TryGetValue(b, out var found) ? new[] { found } : new BindState[0])
                             .ToArray();

            var allStates = leftStates.Concat(new[] { rightState });

            var allNodes = allStates.SelectMany(s => s.Nodes);

            var bind  = leftBinds.Concat(new[] { rightBind }).First();
            var state = allStates.Aggregate(BindState.Empty, (ac, s) => ac.MergeWith(s));

            return(new Graph(
                       allNodes
                       .Aggregate(NodeBinds, (ac, n) => ac.SetItem(n, bind)),
                       BindStates
                       .SetItem(bind, state)
                       )
                   .Propagate(bind, state));
        }
示例#2
0
        private Graph Propagate(Bind b, BindState s, Node n0 = null)
        {
            if (s.Nodes.IsEmpty)
            {
                return(this);
            }
            else
            {
                var g  = this;
                var v0 = s.Val;

                _depth++;
                Log.WriteLine($"{Prefix}PROP {s}");
                _depth++;
                Log.Write($"{Prefix}{v0}");

                var nodes = s.Nodes.ToArray();
                int i = 0, j = 0;
                var v = v0;

                while (true)
                {
                    var n = nodes[i];

                    if (n != n0 || !v.Equals(v0))
                    {
                        Log.WriteLine($" -> {n}");

                        var(g2, v2) = n.Impel(g, v);
                        var v3 = Val.Combine(v, v2);
                        Log.Write($"{Prefix}{v3}");

                        if (!v3.Equals(v))
                        {
                            j = i;
                        }

                        g = g2;
                        v = v3;
                    }

                    i = (i + 1) % nodes.Length;
                    if (i == j)
                    {
                        break;
                    }
                }

                Log.WriteLine();
                _depth -= 2;

                return(new Graph(
                           g.NodeBinds,
                           g.BindStates.SetItem(b, s.WithVal(v))
                           ));
            }
        }
示例#3
0
 public BindState MergeWith(BindState other)
 => new BindState(
     Nodes.Union(other.Nodes),
     Val.Combine(Val, other.Val));