⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logictransformer.java

📁 drools 一个开放源码的规则引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        }

        return transformation.transform( parent );
    }

    interface OrTransformation
    {
        ConditionalElement transform(ConditionalElement element);
    }

    /**
     * Takes any And that has an Or as a child and rewrites it to move the Or
     * upwards
     * 
     * (a||b)&&c
     * 
     * <pre>
     *         and
     *         / \
     *        or  c 
     *       /  \
     *      a    b
     * </pre>
     * 
     * Should become (a&&c)||(b&&c)
     * 
     * <pre>
     *           
     *         or
     *        /  \  
     *       /    \ 
     *      /      \ 
     *    and      and     
     *    / \      / \
     *   a   c    b   c
     * </pre>
     */
    class AndOrTransformation
        implements
        OrTransformation
    {

        public ConditionalElement transform(ConditionalElement and)
        {
            Or or = new Or( );
            determinePermutations( 0,
                                  (And) and,
                                  null,
                                  or );
            return or;
        }

        /**
         * Recursive method that determins all unique combinations of children
         * for the given parent and.
         * 
         * @param currentLevel
         * @param and
         * @param combination
         * @param or
         */
        private void determinePermutations(int currentLevel,
                                          And and,
                                          And combination,
                                          Or or)
        {
            Object entry = and.getChildren( ).get( currentLevel );
            if ( entry instanceof Or )
            {
                // Only OR nodes need to be iterated over
                Or childOr = (Or) entry;
                for ( Iterator it = childOr.getChildren( ).iterator( ); it.hasNext( ); )
                {
                    //Make a temp copy of combinations+new entry which will be sent forward
                    And temp = new And( );
                    if ( currentLevel == 0 )
                    {
                        //Always start with a clean combination
                        combination = new And( );
                    }
                    else
                    {
                        temp.getChildren( ).addAll( combination.getChildren( ) );
                    }

                    //now check for and remove duplicates
                    Object object = it.next( );
                    if ( object instanceof And )
                    {
                        // Can't have duplicate Ands so move up the children
                        And childAnd = (And) object;
                        for ( Iterator childIter = childAnd.getChildren( ).iterator( ); childIter.hasNext( ); )
                        {
                            temp.addChild( childIter.next( ) );
                        }
                    }
                    else
                    {
                        //no duplicates so just add
                        temp.addChild( object );
                    }
                    
                    if ( currentLevel < and.getChildren( ).size( ) - 1 )
                    {
                        //keep recursing to build up the combination until we are at the end where it will be added to or
                        determinePermutations( currentLevel + 1,
                                              and,
                                              temp,
                                              or );
                    }
                    else
                    {
                        //we are at the end so just attach the combination to the or node
                        or.addChild( temp );
                    }
                }
            }
            else
            {
                //Make a temp copy of combinations+new entry which will be sent forward                
                And temp = new And( );
                if ( currentLevel == 0 )
                {
                    //Always start with a clean combination                    
                    combination = new And( );
                }
                else
                {
                    temp.getChildren( ).addAll( combination.getChildren( ) );
                }
                temp.addChild( entry );

                if ( currentLevel < and.getChildren( ).size( ) - 1 )
                {
                    //keep recursing to build up the combination until we are at the end where it will be added to or                    
                    determinePermutations( currentLevel + 1,
                                          and,
                                          temp,
                                          or );
                }
                else
                {
                    //we are at the end so just attach the combination to the or node
                    or.addChild( temp );
                }
            }
        }
    }

    /**
     * (Exist (OR (A B)
     * 
     * <pre>
     *         Exist
     *          | 
     *         or   
     *        /  \
     *       a    b
     * </pre>
     * 
     * (Exist ( Not (a) Not (b)) )
     * 
     * <pre>
     *        Exist   
     *        /   \
     *       Not  Not
     *       |     |
     *       a     b
     * </pre>
     */
    class ExistOrTransformation
        implements
        OrTransformation
    {

        public ConditionalElement transform(ConditionalElement exist)
        {
            if ( !(exist.getChildren( ).get( 0 ) instanceof Or) )
            {
                throw new RuntimeException( "ExistOrTransformation expected '" + Or.class.getName( ) + "' but instead found '" + exist.getChildren( ).get( 0 ).getClass( ).getName( ) + "'" );
            }

            /*
             * we know a Not only ever has one child, and the previous algorithm
             * has confirmed the child is an OR
             */
            Or or = (Or) exist.getChildren( ).get( 0 );
            And and = new And( );
            for ( Iterator it = or.getChildren( ).iterator( ); it.hasNext( ); )
            {
                Exist newExist = new Exist( );
                newExist.addChild( it.next( ) );
                and.addChild( newExist );
            }
            return and;
        }
    }

    /**
     * (Not (OR (A B)
     * 
     * <pre>
     *         Not
     *          | 
     *         or   
     *        /  \
     *       a    b
     * </pre>
     * 
     * (And ( Not (a) Exist (b)) )
     * 
     * <pre>
     *         And   
     *        /   \
     *       Not  Not
     *       |     |
     *       a     b
     * </pre>
     */
    class NotOrTransformation
        implements
        OrTransformation
    {

        public ConditionalElement transform(ConditionalElement not)
        {
            if ( !(not.getChildren( ).get( 0 ) instanceof Or) )
            {
                throw new RuntimeException( "NotOrTransformation expected '" + Or.class.getName( ) + "' but instead found '" + not.getChildren( ).get( 0 ).getClass( ).getName( ) + "'" );
            }

            /*
             * we know a Not only ever has one child, and the previous algorithm
             * has confirmed the child is an OR
             */
            Or or = (Or) not.getChildren( ).get( 0 );
            And and = new And( );
            for ( Iterator it = or.getChildren( ).iterator( ); it.hasNext( ); )
            {
                Not newNot = new Not( );
                newNot.addChild( it.next( ) );
                and.addChild( newNot );
            }
            return and;
        }
    }


    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -