Causal inference with a Bayesian network in Java

package com.bayesserver.examples;

import com.bayesserver.*;
import com.bayesserver.inference.*;

import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import java.text.NumberFormat;

public final class CausalInferenceExample {

    public static void main(String[] args) throws XMLStreamException, IOException, InconsistentEvidenceException {

        var network = new Network();
        network.load("C:\\ProgramData\\Bayes Server 9.5\\Sample Networks\\Causal Inference Simple.bayes");

        var drug = network.getVariables().get("Drug", true);
        var drugTrue = drug.getStates().get("True", true);
        var drugFalse = drug.getStates().get("False", true);

        var recovered = network.getVariables().get("Recovered", true);
        var recoveredTrue = recovered.getStates().get("True", true);

        var factory = new RelevanceTreeInferenceFactory();
        var inference = factory.createInferenceEngine(network);
        var queryOptions = factory.createQueryOptions();
        var queryOutput = factory.createQueryOutput();
        var queryRecovered = new Table(recovered);
        inference.getQueryDistributions().add(queryRecovered);

        var percentFormat = NumberFormat.getPercentInstance();
        percentFormat.setMinimumFractionDigits(2);
        percentFormat.setMaximumFractionDigits(2);

        {
            System.out.println("Non-causal version (incorrect)...");

            // First lets calculate P(Recovered=True|Drug=True) - P(Recovered=True|Drug=False)
            // without an intervention. i.e. non-causally which will give us the wrong result

            inference.getEvidence().setState(drugTrue);
            inference.query(queryOptions, queryOutput);

            var pRecoveredGivenDrugTrue = queryRecovered.get(recoveredTrue);
            inference.getEvidence().setState(drugFalse);
            inference.query(queryOptions, queryOutput);
            var pRecoveredGivenDrugFalse = queryRecovered.get(recoveredTrue);

            var effectivenessNonCausal = pRecoveredGivenDrugTrue - pRecoveredGivenDrugFalse;
            System.out.printf("Effectiveness of drug (non-causal) = %s%n", percentFormat.format(effectivenessNonCausal));

        }

        System.out.println();

        {
            System.out.println("Causal version...");

            // Now lets calculate P(Recovered=True|Do(Drug=True)) - P(Recovered=True|Do(Drug=False))
            // with an intervention. i.e. causally which will give us the correct result

            inference.getEvidence().setState(drugTrue, null, InterventionType.DO);
            inference.query(queryOptions, queryOutput);
            var pRecoveredGivenDoDrugTrue = queryRecovered.get(recoveredTrue);

            inference.getEvidence().setState(drugFalse, null, InterventionType.DO);
            inference.query(queryOptions, queryOutput);
            var pRecoveredGivenDoDrugFalse = queryRecovered.get(recoveredTrue);

            var effectivenessCausal = pRecoveredGivenDoDrugTrue - pRecoveredGivenDoDrugFalse;
            System.out.printf("Effectiveness of drug (causal) = %s%n", percentFormat.format(effectivenessCausal));

        }

        // Expected output:

        // Non-causal version (incorrect)...
        // Effectiveness of drug(non-causal) = -4.91 %

        // Causal version...
        // Effectiveness of drug(causal) = 5.02 %

    }
}