package com.github.pineasaurusrex.inference_engine;

import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

public class TruthTableAlgorithm extends SearchAlgorithm {
    public TruthTableAlgorithm(KnowledgeBase kb) {
        super(kb);
    }

    @Override
    public Optional<SearchAlgorithmResult> entails(Sentence q) {
        // enumerate the models
        // check that q is true in all models in which the KB is true
        List<PropositionalSymbol> symbols = knowledgeBase.getPropositionalSymbols();
        AtomicInteger modelCounter = new AtomicInteger(0);
        boolean entailed = checkAll(q, symbols, new Model(), modelCounter).allMatch(Boolean::booleanValue);
        if (entailed) {
            return Optional.of(new TruthTableAlgorithmResult(modelCounter.get()));
        } else {
            return Optional.empty();
        }

    }

    private Stream<Boolean> checkAll(Sentence q, List<PropositionalSymbol> symbols, Model model, AtomicInteger modelCounter) {
        if (!symbols.isEmpty()) {
            PropositionalSymbol symbol = symbols.get(0);
            List<PropositionalSymbol> remainingSymbols = symbols.subList(1, symbols.size());
            modelCounter.addAndGet(2);

            // possible research: try using multi-threading and exploring it in parallel
            return Stream.of(false, true).flatMap(val -> checkAll(q, remainingSymbols, model.union(symbol, val), modelCounter));
        } else {
            if (model.holdsTrue(knowledgeBase)) {
                return Stream.of(model.holdsTrue(q));
            } else {
                // when KB is false, return true
                return Stream.of(true);
            }
        }
    }
}

@@ -1290,47 +1290,8 @@
 ());
-%0A            modelCounter.addAndGet(2);
 %0A%0A  
@@ -1593,43 +1593,166 @@
     
-return Stream.of(model.holdsTrue(q)
+boolean entailsQuery = model.holdsTrue(q);%0A                if (entailsQuery) %7B modelCounter.incrementAndGet(); %7D%0A                return Stream.of(entailsQuery
 );%0A 

Change the truth table counter