//---------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Diagnostics;
namespace System.Data.Common.Utils.Boolean
{
///
/// Data structure supporting storage of facts and proof (resolution) of queries given
/// those facts.
///
/// For instance, we may know the following facts:
///
/// A --> B
/// A
///
/// Given these facts, the knowledge base can prove the query:
///
/// B
///
/// through resolution.
///
/// Type of leaf term identifiers in fact expressions.
internal class KnowledgeBase
{
private readonly List> _facts;
private Vertex _knowledge;
private readonly ConversionContext _context;
///
/// Initialize a new knowledge base.
///
internal KnowledgeBase()
{
_facts = new List>();
_knowledge = Vertex.One; // we know '1', but nothing else at present
_context = IdentifierService.Instance.CreateConversionContext();
}
///
/// Adds all facts from another knowledge base
///
/// The other knowledge base
internal void AddKnowledgeBase(KnowledgeBase kb)
{
foreach (BoolExpr fact in kb._facts)
{
AddFact(fact);
}
}
///
/// Adds the given fact to this KB.
///
/// Simple fact.
internal virtual void AddFact(BoolExpr fact)
{
_facts.Add(fact);
Converter converter = new Converter(fact, _context);
Vertex factVertex = converter.Vertex;
_knowledge = _context.Solver.And(_knowledge, factVertex);
}
///
/// Adds the given implication to this KB, where implication is of the form:
///
/// condition --> implies
///
/// Condition
/// Entailed expression
internal void AddImplication(BoolExpr condition, BoolExpr implies)
{
AddFact(new Implication(condition, implies));
}
///
/// Adds an equivalence to this KB, of the form:
///
/// left iff. right
///
/// Left operand
/// Right operand
internal void AddEquivalence(BoolExpr left, BoolExpr right)
{
AddFact(new Equivalence(left, right));
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
builder.AppendLine("Facts:");
foreach (BoolExpr fact in _facts)
{
builder.Append("\t").AppendLine(fact.ToString());
}
return builder.ToString();
}
// Private class improving debugging output for implication facts
// (fact appears as A --> B rather than !A + B)
private class Implication : OrExpr
{
BoolExpr _condition;
BoolExpr _implies;
// (condition --> implies) iff. (!condition OR implies)
internal Implication(BoolExpr condition, BoolExpr implies)
: base(condition.MakeNegated(), implies)
{
_condition = condition;
_implies = implies;
}
public override string ToString()
{
return StringUtil.FormatInvariant("{0} --> {1}", _condition, _implies);
}
}
// Private class improving debugging output for equivalence facts
// (fact appears as A <--> B rather than (!A + B) . (A + !B))
private class Equivalence : AndExpr
{
BoolExpr _left;
BoolExpr _right;
// (left iff. right) iff. (left --> right AND right --> left)
internal Equivalence(BoolExpr left, BoolExpr right)
: base(new Implication(left, right), new Implication(right, left))
{
_left = left;
_right = right;
}
public override string ToString()
{
return StringUtil.FormatInvariant("{0} <--> {1}", _left, _right);
}
}
}
}