diff --git a/nars_core_java/nars/inference/CompositionalRules.java b/nars_core_java/nars/inference/CompositionalRules.java
index b0152f564607f94309c1a3c13b03875000da8aba..96c634141b1bd380bfd7fc04de8426f2668fcb66 100644
--- a/nars_core_java/nars/inference/CompositionalRules.java
+++ b/nars_core_java/nars/inference/CompositionalRules.java
@@ -23,10 +23,10 @@ package nars.inference;
 import java.util.*;
 
 import nars.entity.*;
-import nars.language.*;
-import nars.storage.Memory;
 import nars.entity.Task;
 import nars.io.Symbols;
+import nars.language.*;
+import nars.storage.Memory;
 
 /**
  * Compound term composition and decomposition rules, with two premises.
@@ -35,6 +35,118 @@ import nars.io.Symbols;
  * introduction) can also be used backward.
  */
 public final class CompositionalRules {
+    
+    static Term unwrapNegation(Term T) //negation is not counting as depth
+    {
+        if(T!=null && T instanceof Negation)
+            return (Term) ((CompoundTerm)T).getComponents().get(0).clone();
+        return T;
+    }
+    public static Random rand = new Random(1);
+    static boolean dedSecondLayerVariableUnification(Task task, Memory memory)
+    {
+        Sentence taskSentence=task.getSentence();
+        Term taskterm=taskSentence.getContent();
+        if(taskSentence==null || taskSentence.isQuestion()) {
+            return false;
+        }
+        if(taskterm instanceof CompoundTerm && (taskterm instanceof Disjunction || taskterm instanceof Conjunction || taskterm instanceof Equivalence || taskterm instanceof Implication)) { //lets just allow conjunctions, implication and equivalence for now
+            if(!Variable.containVar(taskterm.toString())) {
+                return false;
+            }            
+            Concept second=memory.getConceptBag().takeOut();
+            if(second==null) {
+                return false;
+            }
+            Term secterm=second.getTerm();
+            if(second.getBeliefs()==null || second.getBeliefs().size()==0) {
+                return false;
+            }
+            
+            Sentence second_belief=second.getBeliefs().get(rand.nextInt(second.getBeliefs().size()));
+            TruthValue truthSecond=second_belief.getTruth();
+            //we have to select a random belief
+            ArrayList<HashMap<Term, Term>> terms_dependent=new ArrayList<HashMap<Term, Term>>();
+            ArrayList<HashMap<Term, Term>> terms_independent=new ArrayList<HashMap<Term, Term>>();
+            //ok, we have selected a second concept, we know its most confident truth value, lets now go through taskterms components
+            //for two levels, and remember the terms which unify with second
+            ArrayList<Term> components_level1=((CompoundTerm) taskterm).getComponents();
+            Term secterm_unwrap=unwrapNegation(secterm);
+            for(Term T1 : components_level1) {
+                Term T1_unwrap=unwrapNegation(T1);
+                HashMap<Term, Term> Values = new HashMap<Term, Term>(); //we are only interested in first variables
+                if(Variable.findSubstitute(Symbols.VAR_DEPENDENT, T1_unwrap, secterm_unwrap,Values,new HashMap<Term, Term>())) { 
+                    terms_dependent.add(Values);
+                }
+                HashMap<Term, Term> Values2 = new HashMap<Term, Term>(); //we are only interested in first variables
+                if(Variable.findSubstitute(Symbols.VAR_INDEPENDENT, T1_unwrap, secterm_unwrap,Values2,new HashMap<Term, Term>())) {
+                    terms_independent.add(Values2);
+                }
+                if(!((T1_unwrap instanceof Implication) || (T1_unwrap instanceof Equivalence) || (T1_unwrap instanceof Conjunction) || (T1_unwrap instanceof Disjunction))) {
+                    continue;
+                }
+                if(T1_unwrap instanceof CompoundTerm){// && (T1_unwrap instanceof Disjunction || T1_unwrap instanceof Conjunction)) {
+                    ArrayList<Term> components_level2=((CompoundTerm) T1_unwrap).getComponents();
+                    for(Term T2 : components_level2) {
+                        Term T2_unwrap=unwrapNegation(T2);  
+                        HashMap<Term, Term> Values3 = new HashMap<Term, Term>(); //we are only interested in first variables
+                        if(Variable.findSubstitute(Symbols.VAR_DEPENDENT, T2_unwrap, secterm_unwrap,Values3,new HashMap<Term, Term>())) {
+                            terms_dependent.add(Values3);
+                        }
+                        HashMap<Term, Term> Values4 = new HashMap<Term, Term>(); //we are only interested in first variables
+                        if(Variable.findSubstitute(Symbols.VAR_INDEPENDENT, T2_unwrap, secterm_unwrap,Values4,new HashMap<Term, Term>())) {
+                            terms_independent.add(Values4);
+                        }
+                    }
+                }
+            }
+            Term result;
+            TruthValue truth;
+            double valu=rand.nextDouble();
+            if(!terms_dependent.isEmpty()) { //dependent or independent
+                if(terms_dependent.isEmpty()) {
+                    return false;
+                }
+                HashMap<Term, Term> substi=terms_dependent.get(rand.nextInt(terms_dependent.size()));
+                result=(CompoundTerm)taskterm.clone();
+                ((CompoundTerm)result).applySubstitute(substi);
+                truth=TruthFunctions.anonymousAnalogy(taskSentence.getTruth(), truthSecond);
+                
+                Sentence newSentence = new Sentence(result, Symbols.JUDGMENT_MARK, truth, taskSentence.getStamp());
+                newSentence.getStamp().creationTime=memory.getTime();
+                Stamp useEvidentalbase=new Stamp(taskSentence.getStamp(),second_belief.getStamp(),memory.getTime());
+                newSentence.getStamp().setEvidentalBase(useEvidentalbase.getEvidentalBase());
+                newSentence.getStamp().setBaseLength(useEvidentalbase.getBaseLength());
+                BudgetValue budget = BudgetFunctions.compoundForward(truth, newSentence.getContent(), memory);
+                Task newTask = new Task(newSentence, budget, task, null);
+                Task dummy = new Task(second_belief, budget, task, null);
+                memory.currentBelief=taskSentence;
+                memory.currentTask=dummy;
+                memory.derivedTask(newTask, false, false);
+            }
+            if(!terms_independent.isEmpty()) {
+                HashMap<Term, Term> substi=terms_independent.get(rand.nextInt(terms_independent.size()));
+                result=(CompoundTerm)taskterm.clone();
+                ((CompoundTerm)result).applySubstitute(substi);
+                truth=TruthFunctions.deduction(taskSentence.getTruth(), truthSecond);
+                
+                Sentence newSentence = new Sentence(result, Symbols.JUDGMENT_MARK, truth, taskSentence.getStamp());
+                newSentence.getStamp().creationTime=memory.getTime();
+                Stamp useEvidentalbase=new Stamp(taskSentence.getStamp(),second_belief.getStamp(),memory.getTime());
+                newSentence.getStamp().setEvidentalBase(useEvidentalbase.getEvidentalBase());
+                newSentence.getStamp().setBaseLength(useEvidentalbase.getBaseLength());
+                BudgetValue budget = BudgetFunctions.compoundForward(truth, newSentence.getContent(), memory);
+                Task newTask = new Task(newSentence, budget, task, null);
+                Task dummy = new Task(second_belief, budget, task, null);
+                memory.currentBelief=taskSentence;
+                memory.currentTask=dummy;
+                memory.derivedTask(newTask, false, false);
+            }
+            return true;
+        }
+        return true;
+    }
+    
     /* -------------------- questions which contain answers which are of no value for NARS but need to be answered -------------------- */
     /**
      * {<(*,p1,p2,p3) <-> (*,s1,s2,s3)>?, <(*,p1,p2) <-> (*,s1,s2)>,<(*,p1,p3) <-> (*,s1,s3)>} |- {<(*,p1,p2,p3) <-> (*,s1,s2,s3)>}
diff --git a/nars_core_java/nars/inference/RuleTables.java b/nars_core_java/nars/inference/RuleTables.java
index 0f297d9c1bcced53f29de0d59b2aef108ea1f041..96a9c609108db74ca61862163a0656d8d9e64a57 100644
--- a/nars_core_java/nars/inference/RuleTables.java
+++ b/nars_core_java/nars/inference/RuleTables.java
@@ -53,6 +53,11 @@ public class RuleTables {
         if (belief != null) {
             LocalRules.match(task, belief, memory);
         }
+        Sentence buf1=memory.currentBelief;
+        Task buf2=memory.currentTask;
+        CompositionalRules.dedSecondLayerVariableUnification(task,memory);
+        memory.currentBelief=buf1;
+        memory.currentTask=buf2;
         if (!memory.noResult() && task.getSentence().isJudgment()) {
             return;
         }
diff --git a/nars_core_java/nars/language/Variable.java b/nars_core_java/nars/language/Variable.java
index 0d2d1d6edf6297fd4367f3b38dcf4113fdae221b..6a24d35a065c794d6c08dd1a9ea4d0bd487ee0b8 100644
--- a/nars_core_java/nars/language/Variable.java
+++ b/nars_core_java/nars/language/Variable.java
@@ -174,7 +174,7 @@ public class Variable extends Term {
      * @param map2 The substitution for term2 formed so far
      * @return Whether there is a substitution that unifies the two Terms
      */
-    private static boolean findSubstitute(char type, Term term1, Term term2,
+    public static boolean findSubstitute(char type, Term term1, Term term2,
             HashMap<Term, Term> map1, HashMap<Term, Term> map2) {
         Term t;
         if ((term1 instanceof Variable) && (((Variable) term1).getType() == type)) {
diff --git a/nars_core_java/nars/main_nogui/ReasonerBatch.java b/nars_core_java/nars/main_nogui/ReasonerBatch.java
index 57f58a9216e25f60b4075a5c86fcbe3e798505fb..d20c2f88a1b123bbc2f0b074fde96dca61dbe96c 100644
--- a/nars_core_java/nars/main_nogui/ReasonerBatch.java
+++ b/nars_core_java/nars/main_nogui/ReasonerBatch.java
@@ -1,11 +1,12 @@
 package nars.main_nogui;
 
 import java.util.ArrayList;
+import java.util.Random;
 import java.util.concurrent.atomic.AtomicInteger;
-
 import nars.entity.Stamp;
 import nars.entity.Task;
 import nars.gui.MainWindow;
+import nars.inference.CompositionalRules;
 import nars.io.InputChannel;
 import nars.io.OutputChannel;
 import nars.io.StringParser;
@@ -69,6 +70,7 @@ public class ReasonerBatch {
      * from {@link MainWindow}.
      */
     public void reset() {
+        CompositionalRules.rand=new Random(1);
         running = false;
         walkingSteps = 0;
         clock = 0;