public Term Reduce()
        {
            while (currentNode.HasRedex)
            {
                var reductionResult = TryApply(currentNode);
                if (currentStatus.NeedsSurgery)
                {
                    currentNode = SpliceApplicationResultWithTerm(reductionResult, TreeTraversal.GetNextNodeLRP(currentNode));
                    currentNode = TreeTraversal.GetLowestLeftNode(currentNode.Parent);
                }
                else
                {
                    currentNode = TreeTraversal.GetNextNodeLRP(currentNode);
                }
            }
            var result = TryApply(currentNode);

            if (currentStatus.NeedsSurgery)
            {
                var formerNode = (Term)currentStatus.CurrentApplica;
                if (formerNode == TreeTraversal.GetLowestLeftNode(formerNode.Parent))
                {
                    if (!(result.Right is VoidTerm))
                    {
                        TreeTraversal.RenewRepresentation(formerNode);
                        currentNode   = TreeTraversal.GetLowestLeftNode(result);
                        currentStatus = new ReductionStatus();
                        return(Reduce());
                    }
                    else
                    {
                        formerNode.Parent.Left  = result;
                        formerNode.Parent.Right = new VoidTerm();
                    }
                }
                else
                {
                    formerNode.Parent.Right = result;
                }
                TreeTraversal.RenewRepresentation(formerNode);
                return(formerNode.Parent);
            }

            var toplevel = TreeTraversal.GetToplevelTerm(currentNode);

            if (toplevel.Right == null)
            {
                return(new Term(currentNode, new VoidTerm()));
            }
            else
            {
                return(toplevel);
            }
        }
        public static IObservable <TAcc> Transduce <TAcc, TIn, TOut>(this IObservable <TIn> source, ITransducer <TIn, TOut> transducer, Func <TAcc, TOut, TAcc> reducer, TAcc seed)
        {
            var status = new ReductionStatus();
            var res    = seed;
            var red    = transducer.Transform(status, reducer);

            return(new AnonymousObservable <TAcc>(observer => source.Subscribe(el => {
                if (status.Complete)
                {
                    observer.OnNext(res);
                    observer.OnCompleted();
                    return;
                }
                res = red(res, el);
            }, observer.OnError, () => { observer.OnNext(res); observer.OnCompleted(); })));
        }
        public static IObservable <TOut> Transduce <TIn, TOut>(this IObservable <TIn> source, ITransducer <TIn, TOut> transducer)
        {
            var status  = new ReductionStatus();
            var reducer = transducer.Transform <Optional <TOut> >(status, Utils.Enumerator);

            return(new AnonymousObservable <TOut>(observer => source.Subscribe(el => {
                if (status.Complete)
                {
                    observer.OnCompleted();
                    return;
                }
                var res = reducer(new Optional <TOut>(), el);
                if (res.HasValue)
                {
                    observer.OnNext(res.Value);
                }
            }, observer.OnError, observer.OnCompleted)));
        }
 public Reductor(Term builtTerm)
 {
     this.currentNode   = TreeTraversal.GetLowestLeftNode(builtTerm);
     this.currentStatus = new ReductionStatus();
 }