Experimental code for Tiago Gomes bp solver.
This commit is contained in:
parent
4a5ba35937
commit
29e46cbab9
@ -1985,6 +1985,7 @@ AC_CONFIG_FILES([packages/clib/Makefile])
|
||||
AC_CONFIG_FILES([packages/clib/maildrop/rfc822/Makefile])
|
||||
AC_CONFIG_FILES([packages/clib/maildrop/rfc2045/Makefile])
|
||||
AC_CONFIG_FILES([packages/CLPBN/Makefile])
|
||||
AC_CONFIG_FILES([packages/CLPBN/clpbn/bp/Makefile])
|
||||
AC_CONFIG_FILES([packages/cplint/Makefile])
|
||||
AC_CONFIG_FILES([packages/cplint/approx/simplecuddLPADs/Makefile])
|
||||
AC_CONFIG_FILES([packages/http/Makefile])
|
||||
|
@ -35,6 +35,7 @@ CLPBN_EXDIR = $(srcdir)/clpbn/examples
|
||||
CLPBN_PROGRAMS= \
|
||||
$(CLPBN_SRCDIR)/aggregates.yap \
|
||||
$(CLPBN_SRCDIR)/bnt.yap \
|
||||
$(CLPBN_SRCDIR)/bp.yap \
|
||||
$(CLPBN_SRCDIR)/connected.yap \
|
||||
$(CLPBN_SRCDIR)/discrete_utils.yap \
|
||||
$(CLPBN_SRCDIR)/display.yap \
|
||||
|
157
packages/CLPBN/clpbn/bp.yap
Normal file
157
packages/CLPBN/clpbn/bp.yap
Normal file
@ -0,0 +1,157 @@
|
||||
|
||||
/***********************************
|
||||
|
||||
Belief Propagation in CLP(BN)
|
||||
|
||||
This should connect to C-code.
|
||||
|
||||
*********************************/
|
||||
|
||||
:- module(clpbn_bp, [
|
||||
bp/3,
|
||||
check_if_bp_done/1,
|
||||
init_bp_solver/4,
|
||||
run_bp_solver/3]).
|
||||
|
||||
|
||||
:- use_module(library('clpbn/aggregates'),
|
||||
[check_for_agg_vars/2]).
|
||||
|
||||
:- use_module(library('clpbn/connected'),
|
||||
[init_influences/3,
|
||||
influences/5
|
||||
]).
|
||||
|
||||
:- use_module(library('clpbn/dists'),
|
||||
[dist/4,
|
||||
get_dist_domain/2,
|
||||
get_dist_params/2
|
||||
]).
|
||||
|
||||
:- use_module(library('clpbn/display'),
|
||||
[clpbn_bind_vals/3]).
|
||||
|
||||
:-use_module(library(lists),
|
||||
[append/3,
|
||||
memberchk/2
|
||||
]).
|
||||
|
||||
:- load_foreign_files(['horus'], [], init_predicates).
|
||||
|
||||
:- attribute all_diffs/1.
|
||||
|
||||
|
||||
check_if_bp_done(_Var).
|
||||
|
||||
%
|
||||
% implementation of belief propagation
|
||||
%
|
||||
% A1 = +QueryVars -> sets of independent marginalization variables
|
||||
% A2 = *AllVars -> list of all variables
|
||||
% A3 = -Output -> output probabilities
|
||||
%
|
||||
% Other important variables:
|
||||
%
|
||||
% State0 initialized graph, is used to pass data from initialization
|
||||
% to query solving (eg, State might be the JT and be used to run
|
||||
% different queries).
|
||||
%
|
||||
bp([[]],_,_) :- !.
|
||||
bp([QueryVars],AllVars,Output) :-
|
||||
writeln(queryVars:QueryVars),
|
||||
writeln(allVars:AllVars),
|
||||
% init_bp_solver([QueryVars], AllVars, Output, State),
|
||||
run_bp_solver([QueryVars], [AllVars], _State),
|
||||
% bind probs back to variables so that they can be output.
|
||||
clpbn_bind_vals([QueryVars],[LPs],Output).
|
||||
|
||||
% initialise necessary data for query solver
|
||||
init_bp_solver(Qs, AllVars, _, graph(LVis)) :-
|
||||
% replace average, max, min and friends by binary nodes.
|
||||
check_for_agg_vars(AllVars, UnFoldedVars),
|
||||
% replace the variables reachable from G
|
||||
init_influences(UnfoldedVars, G, RG),
|
||||
init_bp_solver_for_questions(Qs, G, RG, _, LVis).
|
||||
|
||||
init_bp_solver_for_questions([], _, _, [], []).
|
||||
init_bp_solver_for_questions([Vs|MVs], G, RG, [NVs|MNVs0], [NVs|LVis]) :-
|
||||
% find variables connectd to Vs
|
||||
influences(Vs, _, NVs0, G, RG),
|
||||
sort(NVs0, NVs),
|
||||
init_bp_solver_for_questions(MVs, G, RG, MNVs0, LVis).
|
||||
|
||||
|
||||
% use a findall to recover space without needing for GC
|
||||
run_bp_solver(LVs, LPs, _) :-
|
||||
findall(Ps, solve_bp(LVs, LPs, Ps), LPs).
|
||||
|
||||
|
||||
solve_bp([LVs|_], [NVs0|_], Ps) :-
|
||||
get_vars_info(NVs0, LVi),
|
||||
get_dists_info(NVs0, Dists),
|
||||
process(LVi, Dists, LVs, Ps).
|
||||
solve_bp([_|MoreLVs], [_|MoreLVis], Ps) :-
|
||||
solve_bp(MoreLVs, MoreLVis, Ps).
|
||||
|
||||
|
||||
get_vars_info([], []).
|
||||
get_vars_info([V|Vs], [var(V, Id, Parents, NParents, Ev)|LV]) :-
|
||||
clpbn:get_atts(V, [dist(Id, Parents)]), !,
|
||||
length(Parents, NParents),
|
||||
get_evidence(V, Ev),
|
||||
get_vars_info(Vs, LV).
|
||||
get_vars_info([_|Vs], LV) :-
|
||||
get_vars_info(Vs, LV).
|
||||
|
||||
|
||||
get_evidence(V, Ev) :-
|
||||
clpbn:get_atts(V, [evidence(Ev)]), !.
|
||||
get_evidence(V, -1). % no evidence !!!
|
||||
|
||||
|
||||
get_dists_info([],[]).
|
||||
get_dists_info([V|Vs], [dist(Id, Domain, DSize, Params, NParams) | Dists]) :-
|
||||
clpbn:get_atts(V, [dist(Id, _)]), !,
|
||||
get_dist_domain(Id, Domain),
|
||||
length(Domain, DSize),
|
||||
get_dist_params(Id, Params),
|
||||
length(Params, NParams),
|
||||
get_dists_info(Vs, Dists).
|
||||
get_dists_info([_|Vs], Dists) :-
|
||||
get_dists_info(Vs, Dists).
|
||||
|
||||
|
||||
% +Vars is a list containing info about every clpbn variables
|
||||
% +Dists is a list containing info about distributions
|
||||
% +QVs is a list containing the query variables
|
||||
% -Out is some output term stating the probabilities
|
||||
process(Vars, Dists, QVs, Out) :-
|
||||
write('vars = '), writeln(Vars),
|
||||
order_vars(Vars, [], OrderedVars),
|
||||
write('ovars = '), writeln(OrderedVars),
|
||||
write('dists = '), writeln(Dists),
|
||||
write('qvs = '), writeln(QVs),
|
||||
length(OrderedVars, NVars),
|
||||
length(Dists, NDists),
|
||||
%create_network(OrderedVars, NVars, Dists, NDists, BNet),
|
||||
length(QVs, NQVs),
|
||||
run_solver(BNet, QVs, NQVs, Out),
|
||||
free_memory(BNet).
|
||||
|
||||
|
||||
order_vars([V], _, [V]) :- !.
|
||||
order_vars([var(V, Id, Parents, NParents, Ev)|Vs], ParsedVars, [var(V, Id, Parents, NParents, Ev)|OrderedVars]) :-
|
||||
\+ memberchk(V, ParsedVars),
|
||||
parents_defined(Parents, ParsedVars), !,
|
||||
order_vars(Vs, [V|ParsedVars], OrderedVars).
|
||||
order_vars([var(V, Id, Parents, NParents, Ev)|Vs], ParsedVars, OrderedVars) :-
|
||||
append(Vs, [var(V, Id, Parents, NParents, Ev)], NVs),
|
||||
order_vars(NVs, ParsedVars, OrderedVars).
|
||||
|
||||
|
||||
parents_defined([], _) :- !.
|
||||
parents_defined([Parent|Parents], ParsedVars) :-
|
||||
memberchk(Parent, ParsedVars),
|
||||
parents_defined(Parents, ParsedVars).
|
||||
|
||||
% f(F), b(B). ----> FAIL
|
208
packages/CLPBN/clpbn/bp/BayesianNetwork.cpp
Normal file
208
packages/CLPBN/clpbn/bp/BayesianNetwork.cpp
Normal file
@ -0,0 +1,208 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "BayesianNetwork.h"
|
||||
#include "BayesianNode.h"
|
||||
|
||||
BayesianNetwork::BayesianNetwork (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
BayesianNetwork::~BayesianNetwork (void)
|
||||
{
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
delete nodes_[i];
|
||||
}
|
||||
for (unsigned int i = 0; i < dists_.size(); i++) {
|
||||
delete dists_[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BayesianNetwork::addNode (string varName,
|
||||
vector<BayesianNode*> parents,
|
||||
int evidence,
|
||||
int distId)
|
||||
{
|
||||
for (unsigned int i = 0; i < dists_.size(); i++) {
|
||||
if (dists_[i]->id == distId) {
|
||||
BayesianNode* node = new BayesianNode (varName, parents,
|
||||
dists_[i], evidence);
|
||||
nodes_.push_back (node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BayesianNetwork::addNode (string varName,
|
||||
vector<BayesianNode*> parents,
|
||||
double* params,
|
||||
int nParams,
|
||||
vector<string> domain)
|
||||
{
|
||||
Distribution* dist = new Distribution (params, nParams, domain);
|
||||
BayesianNode* node = new BayesianNode (varName, parents, dist);
|
||||
dists_.push_back (dist);
|
||||
nodes_.push_back (node);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BayesianNode*
|
||||
BayesianNetwork::getNode (string varName) const
|
||||
{
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
if (nodes_[i]->getVariableName() == varName) {
|
||||
return nodes_[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BayesianNetwork::addDistribution (int distId,
|
||||
double* params,
|
||||
int nParams,
|
||||
vector<string> domain)
|
||||
{
|
||||
dists_.push_back (new Distribution (distId, params, nParams, domain));
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<BayesianNode*>
|
||||
BayesianNetwork::getNodes (void) const
|
||||
{
|
||||
return nodes_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<BayesianNode*>
|
||||
BayesianNetwork::getRootNodes (void) const
|
||||
{
|
||||
vector<BayesianNode*> roots;
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
if (nodes_[i]->isRoot()) {
|
||||
roots.push_back (nodes_[i]);
|
||||
}
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<BayesianNode*>
|
||||
BayesianNetwork::getLeafNodes (void) const
|
||||
{
|
||||
vector<BayesianNode*> leafs;
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
if (nodes_[i]->isLeaf()) {
|
||||
leafs.push_back (nodes_[i]);
|
||||
}
|
||||
}
|
||||
return leafs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BayesianNetwork::isPolyTree (void) const
|
||||
{
|
||||
return !containsCycle();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BayesianNetwork::printNetwork (void) const
|
||||
{
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
cout << *nodes_[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BayesianNetwork::containsCycle (void) const
|
||||
{
|
||||
vector<bool> visited (nodes_.size());
|
||||
for (unsigned int v = 0; v < nodes_.size(); v++) {
|
||||
visited[v] = false;
|
||||
}
|
||||
|
||||
for (unsigned int v = 0; v < nodes_.size(); v++) {
|
||||
if (!visited[v]) {
|
||||
if (containsCycle (v, -1, visited)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BayesianNetwork::containsCycle (int v,
|
||||
int predecessor,
|
||||
vector<bool>& visited) const
|
||||
{
|
||||
visited[v] = true;
|
||||
vector<int> adjs = getAdjacentVertexes (v);
|
||||
for (unsigned int i = 0; i < adjs.size(); i++) {
|
||||
int w = adjs[i];
|
||||
if (!visited[w]) {
|
||||
if (containsCycle (w, v, visited)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (visited[w] && w != predecessor) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // no cycle detected in this component
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
BayesianNetwork::getIndexOf (const BayesianNode* node) const
|
||||
{
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
if (node == nodes_[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<int>
|
||||
BayesianNetwork::getAdjacentVertexes (int v) const
|
||||
{
|
||||
vector<int> adjs;
|
||||
vector<BayesianNode*> parents = nodes_[v]->getParents();
|
||||
vector<BayesianNode*> childs = nodes_[v]->getChilds();
|
||||
for (unsigned int i = 0; i < parents.size(); i++) {
|
||||
adjs.push_back (getIndexOf (parents[i]));
|
||||
}
|
||||
for (unsigned int i = 0; i < childs.size(); i++) {
|
||||
adjs.push_back (getIndexOf (childs[i]));
|
||||
}
|
||||
return adjs;
|
||||
}
|
||||
|
46
packages/CLPBN/clpbn/bp/BayesianNetwork.h
Normal file
46
packages/CLPBN/clpbn/bp/BayesianNetwork.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef BAYESIAN_NETWORK_H
|
||||
#define BAYESIAN_NETWORK_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BayesianNode;
|
||||
class Distribution;
|
||||
|
||||
class BayesianNetwork
|
||||
{
|
||||
public:
|
||||
// constructs
|
||||
BayesianNetwork (void);
|
||||
// destruct
|
||||
virtual ~BayesianNetwork (void);
|
||||
// methods
|
||||
virtual void addNode (string, vector<BayesianNode*>, int, int);
|
||||
virtual void addNode (string, vector<BayesianNode*>,
|
||||
double*, int, vector<string>);
|
||||
BayesianNode* getNode (string) const;
|
||||
void addDistribution (int, double*, int, vector<string>);
|
||||
vector<BayesianNode*> getNodes (void) const;
|
||||
vector<BayesianNode*> getRootNodes (void) const;
|
||||
vector<BayesianNode*> getLeafNodes (void) const;
|
||||
bool isPolyTree (void) const;
|
||||
void printNetwork (void) const;
|
||||
|
||||
protected:
|
||||
// members
|
||||
vector<BayesianNode*> nodes_;
|
||||
vector<Distribution*> dists_;
|
||||
|
||||
private:
|
||||
BayesianNetwork (const BayesianNetwork&); // disallow copy
|
||||
void operator= (const BayesianNetwork&); // disallow assign
|
||||
bool containsCycle (void) const;
|
||||
bool containsCycle (int, int, vector<bool>&) const;
|
||||
int getIndexOf (const BayesianNode*) const;
|
||||
vector<int> getAdjacentVertexes (int) const ;
|
||||
};
|
||||
|
||||
#endif // BAYESIAN_NETWORK_H
|
||||
|
382
packages/CLPBN/clpbn/bp/BayesianNode.cpp
Normal file
382
packages/CLPBN/clpbn/bp/BayesianNode.cpp
Normal file
@ -0,0 +1,382 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cassert>
|
||||
|
||||
#include "BayesianNode.h"
|
||||
#include "CptEntry.h"
|
||||
|
||||
|
||||
BayesianNode::BayesianNode (string varName,
|
||||
vector<BayesianNode*> parents,
|
||||
Distribution* dist,
|
||||
int evidence)
|
||||
{
|
||||
varName_ = varName;
|
||||
parents_ = parents;
|
||||
dist_ = dist;
|
||||
evidence_ = evidence;
|
||||
for (unsigned int i = 0; i < parents.size(); i++) {
|
||||
parents[i]->addChild (this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
BayesianNode::~BayesianNode (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
BayesianNode::getVariableName (void) const
|
||||
{
|
||||
return varName_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<BayesianNode*>
|
||||
BayesianNode::getParents (void) const
|
||||
{
|
||||
return parents_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<BayesianNode*>
|
||||
BayesianNode::getChilds (void) const
|
||||
{
|
||||
return childs_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BayesianNode::addChild (BayesianNode* node)
|
||||
{
|
||||
childs_.push_back (node);
|
||||
}
|
||||
|
||||
|
||||
|
||||
double*
|
||||
BayesianNode::getParameters (void)
|
||||
{
|
||||
return dist_->params;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double*
|
||||
BayesianNode::getRow (int rowIndex) const
|
||||
{
|
||||
int offset = getRowSize() * rowIndex;
|
||||
return &dist_->params[offset];
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
BayesianNode::getProbability (CptEntry& entry)
|
||||
{
|
||||
int index = entry.getCptIndex();
|
||||
return dist_->params[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BayesianNode::setProbability (CptEntry& entry, double prob)
|
||||
{
|
||||
int index = entry.getCptIndex();
|
||||
dist_->params[index] = prob;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BayesianNode::isRoot (void)
|
||||
{
|
||||
return parents_.empty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BayesianNode::isLeaf (void)
|
||||
{
|
||||
return childs_.empty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
BayesianNode::getRowSize (void) const
|
||||
{
|
||||
return dist_->nParams / dist_->domain.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
BayesianNode::getCptSize (void)
|
||||
{
|
||||
return dist_->nParams;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<string>
|
||||
BayesianNode::getDomain (void) const
|
||||
{
|
||||
return dist_->domain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
BayesianNode::getDomainSize (void) const
|
||||
{
|
||||
return dist_->domain.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<CptEntry>
|
||||
BayesianNode::getCptEntries (const vector<pair<int,int> >& constraints)
|
||||
{
|
||||
vector<CptEntry> matchedEntries;
|
||||
if (constraints.size() > 0 && constraints[0].first == 0) {
|
||||
vector<CptEntry> entries = getCptEntriesOfRow (constraints[0].second);
|
||||
for (unsigned int i = 0; i < entries.size(); i++) {
|
||||
if (entries[i].matchConstraints (constraints)) {
|
||||
matchedEntries.push_back (entries[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (unsigned int i = 0; i < dist_->domain.size(); i++) {
|
||||
vector<CptEntry> entries = getCptEntriesOfRow (i);
|
||||
for (unsigned int j = 0; j < entries.size(); j++) {
|
||||
if (entries[j].matchConstraints (constraints)) {
|
||||
matchedEntries.push_back (entries[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return matchedEntries;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<CptEntry>
|
||||
BayesianNode::getCptEntriesOfRow (int rowIndex)
|
||||
{
|
||||
int rowSize = getRowSize();
|
||||
int nParents = parents_.size();
|
||||
vector<vector<int> > insts (rowSize);
|
||||
|
||||
for (int i = 0; i < rowSize; i++) {
|
||||
insts[i].resize (nParents + 1);
|
||||
insts[i][0] = rowIndex;
|
||||
}
|
||||
|
||||
int reps = 1;
|
||||
for (int i = nParents - 1; i >= 0; i--) {
|
||||
int index = 0;
|
||||
while (index < rowSize) {
|
||||
for (int j = 0; j < parents_[i]->getDomainSize(); j++) {
|
||||
for (int k = 0; k < reps; k++) {
|
||||
insts[index][i + 1] = j;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
reps *= parents_[i]->getDomainSize();
|
||||
}
|
||||
|
||||
vector<CptEntry> entries;
|
||||
for (int i = 0; i < rowSize; i++ ) {
|
||||
entries.push_back (CptEntry ((rowIndex * rowSize) + i, insts[i]));
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
BayesianNode::getIndexOfParent (const BayesianNode* myParent) const
|
||||
{
|
||||
for (unsigned int i = 0; i < parents_.size(); i++) {
|
||||
if (myParent == parents_[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BayesianNode::hasEvidence (void)
|
||||
{
|
||||
return evidence_ != -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
BayesianNode::getEvidence (void)
|
||||
{
|
||||
return evidence_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BayesianNode::setEvidence (int evidence)
|
||||
{
|
||||
evidence_ = evidence;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
BayesianNode::entryToString (const CptEntry& entry) const
|
||||
{
|
||||
string s = "p(" ;
|
||||
vector<int> insts = entry.getDomainInstantiations();
|
||||
s += getDomain()[insts[0]];
|
||||
if (parents_.size() > 0) {
|
||||
s += "|" ;
|
||||
for (unsigned int i = 1; i < insts.size() - 1; i++) {
|
||||
s += parents_[i - 1]->getDomain()[insts[i]] + ",";
|
||||
}
|
||||
BayesianNode* lastParent = parents_[parents_.size() - 1];
|
||||
int lastIndex = insts[insts.size() - 1];
|
||||
s += lastParent->getDomain()[lastIndex];
|
||||
}
|
||||
s += ")" ;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<string>
|
||||
BayesianNode::getDomainHeaders (void) const
|
||||
{
|
||||
int rowSize = getRowSize();
|
||||
int nParents = parents_.size();
|
||||
int reps = 1;
|
||||
vector<string> headers (rowSize);
|
||||
for (int i = nParents - 1; i >= 0; i--) {
|
||||
vector<string> domain = parents_[i]->getDomain();
|
||||
int index = 0;
|
||||
while (index < rowSize) {
|
||||
for (int j = 0; j < parents_[i]->getDomainSize(); j++) {
|
||||
for (int k = 0; k < reps; k++) {
|
||||
if (headers[index] != "") {
|
||||
headers[index] = domain[j] + "," + headers[index];
|
||||
} else {
|
||||
headers[index] = domain[j];
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
reps *= parents_[i]->getDomainSize();
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostream&
|
||||
operator << (ostream& o, const BayesianNode& node)
|
||||
{
|
||||
o << "Variable: " << node.getVariableName() << endl;
|
||||
|
||||
o << "Domain: " ;
|
||||
vector<string> domain = node.dist_->domain;
|
||||
for (unsigned int i = 0; i < domain.size() - 1; i++) {
|
||||
o << domain[i] << ", " ;
|
||||
}
|
||||
if (domain.size() != 0) {
|
||||
o << domain[domain.size() - 1];
|
||||
}
|
||||
o << endl;
|
||||
|
||||
o << "Parents: " ;
|
||||
vector<BayesianNode*> parents = node.getParents();
|
||||
if (parents.size() != 0) {
|
||||
for (unsigned int i = 0; i < parents.size() - 1; i++) {
|
||||
o << parents[i]->getVariableName() << ", " ;
|
||||
}
|
||||
o << parents[parents.size() - 1]->getVariableName();
|
||||
}
|
||||
o << endl;
|
||||
|
||||
o << "Childs: " ;
|
||||
vector<BayesianNode*> childs = node.getChilds();
|
||||
if (childs.size() != 0) {
|
||||
for (unsigned int i = 0; i < childs.size() - 1; i++) {
|
||||
o << childs[i]->getVariableName() << ", " ;
|
||||
}
|
||||
o << childs[childs.size() - 1]->getVariableName();
|
||||
}
|
||||
o << endl;
|
||||
|
||||
const unsigned int MIN_DOMAIN_WIDTH = 4; // min width of first column
|
||||
const unsigned int MIN_COMBO_WIDTH = 12; // min width of following columns
|
||||
|
||||
unsigned int domainWidth = domain[0].length();
|
||||
for (unsigned int i = 1; i < domain.size(); i++) {
|
||||
if (domain[i].length() > domainWidth) {
|
||||
domainWidth = domain[i].length();
|
||||
}
|
||||
}
|
||||
|
||||
domainWidth = (domainWidth < MIN_DOMAIN_WIDTH)
|
||||
? MIN_DOMAIN_WIDTH
|
||||
: domainWidth;
|
||||
|
||||
o << left << setw (domainWidth) << "cpt" << right;
|
||||
|
||||
vector<int> widths;
|
||||
int lineWidth = domainWidth;
|
||||
vector<string> headers = node.getDomainHeaders();
|
||||
if (!headers.empty()) {
|
||||
for (unsigned int i = 0; i < headers.size(); i++) {
|
||||
unsigned int len = headers[i].length();
|
||||
int w = (len < MIN_COMBO_WIDTH) ? MIN_COMBO_WIDTH : len;
|
||||
widths.push_back (w);
|
||||
o << setw (w) << headers[i];
|
||||
lineWidth += w;
|
||||
}
|
||||
o << endl;
|
||||
} else {
|
||||
cout << endl;
|
||||
widths.push_back (domainWidth);
|
||||
lineWidth += MIN_COMBO_WIDTH;
|
||||
}
|
||||
|
||||
for (int i = 0; i < lineWidth; i++) {
|
||||
o << "-" ;
|
||||
}
|
||||
o << endl;
|
||||
|
||||
for (unsigned int i = 0; i < domain.size(); i++) {
|
||||
double* row = node.getRow (i);
|
||||
o << left << setw (domainWidth) << domain[i] << right;
|
||||
for (int j = 0; j < node.getRowSize(); j++) {
|
||||
o << setw (widths[j]) << row[j];
|
||||
}
|
||||
o << endl;
|
||||
}
|
||||
o << endl;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
59
packages/CLPBN/clpbn/bp/BayesianNode.h
Normal file
59
packages/CLPBN/clpbn/bp/BayesianNode.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef BAYESIAN_NODE_H
|
||||
#define BAYESIAN_NODE_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "Distribution.h"
|
||||
#include "CptEntry.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BayesianNode
|
||||
{
|
||||
public:
|
||||
// constructs
|
||||
BayesianNode (string, vector<BayesianNode*>, Distribution*, int = -1);
|
||||
// destruct
|
||||
~BayesianNode (void);
|
||||
// methods
|
||||
string getVariableName (void) const;
|
||||
vector<BayesianNode*> getParents (void) const;
|
||||
vector<BayesianNode*> getChilds (void) const;
|
||||
void addChild (BayesianNode*);
|
||||
double* getParameters (void);
|
||||
double* getRow (int) const;
|
||||
double getProbability (CptEntry&);
|
||||
void setProbability (CptEntry&, double);
|
||||
bool isRoot (void);
|
||||
bool isLeaf (void);
|
||||
int getRowSize (void) const;
|
||||
int getCptSize (void);
|
||||
vector<string> getDomain (void) const;
|
||||
int getDomainSize (void) const;
|
||||
vector<CptEntry> getCptEntries (const vector<pair<int, int> >&);
|
||||
vector<CptEntry> getCptEntriesOfRow (int);
|
||||
int getIndexOfParent (const BayesianNode*) const;
|
||||
bool hasEvidence (void);
|
||||
int getEvidence (void);
|
||||
void setEvidence (int);
|
||||
string entryToString (const CptEntry& entry) const;
|
||||
|
||||
private:
|
||||
BayesianNode (const BayesianNode&); // disallow copy
|
||||
void operator= (const BayesianNode&); // disallow assign
|
||||
// methods
|
||||
vector<string> getDomainHeaders (void) const;
|
||||
friend ostream& operator << (ostream&, const BayesianNode&);
|
||||
// members
|
||||
string varName_; // variable name
|
||||
vector<BayesianNode*> parents_; // parents of this node
|
||||
vector<BayesianNode*> childs_; // children of this node
|
||||
Distribution* dist_;
|
||||
int evidence_;
|
||||
};
|
||||
|
||||
ostream& operator << (ostream&, const BayesianNode&);
|
||||
|
||||
#endif // BAYESIAN_NODE_H
|
||||
|
117
packages/CLPBN/clpbn/bp/BifInterface.cpp
Normal file
117
packages/CLPBN/clpbn/bp/BifInterface.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include "xmlParser/xmlParser.h"
|
||||
|
||||
#include "BifInterface.h"
|
||||
#include "BayesianNetwork.h"
|
||||
#include "BayesianNode.h"
|
||||
|
||||
|
||||
void
|
||||
BifInterface::createNetworkFromXML (BayesianNetwork* bn, const char* fileName)
|
||||
{
|
||||
map<string, vector<string> > domains;
|
||||
XMLNode xMainNode = XMLNode::openFileHelper (fileName, "BIF");
|
||||
// only the first network is parsed, others are ignored
|
||||
XMLNode xNode = xMainNode.getChildNode ("NETWORK");
|
||||
int nVars = xNode.nChildNode ("VARIABLE");
|
||||
for (int i = 0; i < nVars; i++) {
|
||||
XMLNode var = xNode.getChildNode ("VARIABLE", i);
|
||||
string type = var.getAttribute ("TYPE");
|
||||
if (type != "nature") {
|
||||
cerr << "error: only \"nature\" variables are supported" << endl;
|
||||
abort();
|
||||
}
|
||||
vector<string> domain;
|
||||
string varName = var.getChildNode("NAME").getText();
|
||||
int domainSize = var.nChildNode ("OUTCOME");
|
||||
for (int j = 0; j < domainSize; j++) {
|
||||
domain.push_back (var.getChildNode("OUTCOME", j).getText());
|
||||
}
|
||||
domains.insert (make_pair (varName, domain));
|
||||
}
|
||||
|
||||
int nDefs = xNode.nChildNode ("DEFINITION");
|
||||
if (nVars != nDefs) {
|
||||
cerr << "error: different number of variables and definitions";
|
||||
cerr << endl;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nDefs; i++) {
|
||||
XMLNode def = xNode.getChildNode ("DEFINITION", i);
|
||||
string nodeName = def.getChildNode("FOR").getText();
|
||||
map<string, vector<string> >::const_iterator iter = domains.find (nodeName);
|
||||
if (iter == domains.end()) {
|
||||
cerr << "error: unknow variable `" << nodeName << "'" << endl;
|
||||
abort();
|
||||
}
|
||||
vector<BayesianNode*> parents;
|
||||
int nParams = iter->second.size();
|
||||
for (int j = 0; j < def.nChildNode ("GIVEN"); j++) {
|
||||
string parentName = def.getChildNode("GIVEN", j).getText();
|
||||
BayesianNode* parentNode = bn->getNode (parentName);
|
||||
if (parentNode) {
|
||||
nParams *= parentNode->getDomainSize();
|
||||
parents.push_back (parentNode);
|
||||
}
|
||||
else {
|
||||
cerr << "error: unknow variable `" << parentName << "'" << endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int c = 0;
|
||||
double* params = new double [nParams];
|
||||
stringstream s (def.getChildNode("TABLE").getText());
|
||||
while (!s.eof() && c < nParams) {
|
||||
s >> params[c];
|
||||
c++;
|
||||
}
|
||||
if (c != nParams) {
|
||||
cerr << "error: invalid number of parameters " ;
|
||||
cerr << "for variable `" << nodeName << "'" << endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
params = reorderParameters (params, nParams, iter->second.size());
|
||||
bn->addNode (nodeName, parents, params, nParams, iter->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double*
|
||||
BifInterface::reorderParameters (double* params,
|
||||
int nParams,
|
||||
int domainSize)
|
||||
{
|
||||
// the interchange format for bayesian networks saves the probabilities
|
||||
// in the following order:
|
||||
// p(a1|b1,c1) p(a2|b1,c1) p(a1|b1,c2) p(a2|b1,c2) p(a1|b2,c1) p(a2|b2,c1)
|
||||
// p(a1|b2,c2) p(a2|b2,c2).
|
||||
//
|
||||
// however, in clpbn we keep the probabilities in this order:
|
||||
// p(a1|b1,c1) p(a1|b1,c2) p(a1|b2,c1) p(a1|b2,c2) p(a2|b1,c1) p(a2|b1,c2)
|
||||
// p(a2|b2,c1) p(a2|b2,c2).
|
||||
|
||||
int count = 0;
|
||||
int index1 = 0;
|
||||
int index2 = 0;
|
||||
int rowSize = nParams / domainSize;
|
||||
double* reordered = new double [nParams];
|
||||
|
||||
while (index1 < nParams) {
|
||||
index2 = count;
|
||||
for (int i = 0; i < domainSize; i++) {
|
||||
reordered[index2] = params[index1];
|
||||
index1 += 1;
|
||||
index2 += rowSize;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
delete [] params;
|
||||
return reordered;
|
||||
}
|
||||
|
20
packages/CLPBN/clpbn/bp/BifInterface.h
Normal file
20
packages/CLPBN/clpbn/bp/BifInterface.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef BIF_INTERFACE_H
|
||||
#define BIF_INTERFACE_H
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BayesianNetwork;
|
||||
class BayesianNode;
|
||||
|
||||
class BifInterface
|
||||
{
|
||||
public:
|
||||
static void createNetworkFromXML (BayesianNetwork*, const char*);
|
||||
|
||||
private:
|
||||
static double* reorderParameters (double*, int, int);
|
||||
};
|
||||
|
||||
#endif // BIF_INTERFACE_H
|
||||
|
||||
|
36
packages/CLPBN/clpbn/bp/BifTest.cpp
Normal file
36
packages/CLPBN/clpbn/bp/BifTest.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "BayesianNetwork.h"
|
||||
#include "BayesianNode.h"
|
||||
#include "BpNetwork.h"
|
||||
#include "BpNode.h"
|
||||
#include "BifInterface.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
BpNetwork bn;
|
||||
// BayesianNetwork bn;
|
||||
BifInterface::createNetworkFromXML (&bn, argv[1]);
|
||||
bn.printNetwork();
|
||||
|
||||
// bn.getNode("FreightTruck")->setEvidence (0);
|
||||
// bn.getNode("Alarm")->setEvidence (0);
|
||||
|
||||
// bn.setSolverParameters (SEQUENTIAL_SCHEDULE, 500, 0.001);
|
||||
// bn.setSolverParameters (PARALLEL_SCHEDULE, 500, 0.00000000000001);
|
||||
// bn.setSolverParameters (PARALLEL_SCHEDULE, 500, 0.0000000000000000000001);
|
||||
|
||||
//bn.getNode ("F")->setEvidence (0);
|
||||
vector<BayesianNode*> queryVars;
|
||||
//queryVars.push_back (bn.getNode ("D"));
|
||||
//queryVars.push_back (bn.getNode ("Burglar"));
|
||||
queryVars.push_back (bn.getNode ("FreightTruck"));
|
||||
queryVars.push_back (bn.getNode ("Alarm"));
|
||||
bn.runSolver (queryVars);
|
||||
|
||||
// bn.printCurrentStatus();
|
||||
// bn.printBeliefs();
|
||||
return 0;
|
||||
}
|
811
packages/CLPBN/clpbn/bp/BpNetwork.cpp
Normal file
811
packages/CLPBN/clpbn/bp/BpNetwork.cpp
Normal file
@ -0,0 +1,811 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
#include "BpNetwork.h"
|
||||
#include "BpNode.h"
|
||||
#include "CptEntry.h"
|
||||
|
||||
BpNetwork::BpNetwork (void)
|
||||
{
|
||||
schedule_ = SEQUENTIAL_SCHEDULE;
|
||||
maxIter_ = 150;
|
||||
stableThreashold_ = 0.00000000000000000001;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BpNetwork::~BpNetwork (void)
|
||||
{
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
delete nodes_[i];
|
||||
}
|
||||
nodes_.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::setSolverParameters (Schedule schedule,
|
||||
int maxIter,
|
||||
double stableThreashold)
|
||||
{
|
||||
if (maxIter <= 0) {
|
||||
cerr << "error: maxIter must be greater or equal to 1" << endl;
|
||||
abort();
|
||||
}
|
||||
if (stableThreashold <= 0.0 || stableThreashold >= 1.0) {
|
||||
cerr << "error: stableThreashold must be greater than 0.0 " ;
|
||||
cerr << "and lesser than 1.0" << endl;
|
||||
abort();
|
||||
}
|
||||
schedule_ = schedule;
|
||||
maxIter_ = maxIter;
|
||||
stableThreashold_ = stableThreashold;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::runSolver (BayesianNode* queryVar)
|
||||
{
|
||||
vector<BayesianNode*> queryVars;
|
||||
queryVars.push_back (queryVar);
|
||||
runSolver (queryVars);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::runSolver (vector<BayesianNode*> queryVars)
|
||||
{
|
||||
if (queryVars.size() > 1) {
|
||||
addJunctionNode (queryVars);
|
||||
}
|
||||
else {
|
||||
string varName = queryVars[0]->getVariableName();
|
||||
queryNode_ = static_cast<BpNode*> (getNode (varName));
|
||||
}
|
||||
|
||||
if (!isPolyTree()) {
|
||||
if (DL_ >= 1) {
|
||||
cout << "The graph is not single connected. " ;
|
||||
cout << "Iterative belief propagation will be used." ;
|
||||
cout << endl << endl;
|
||||
}
|
||||
schedule_ = PARALLEL_SCHEDULE;
|
||||
}
|
||||
|
||||
if (schedule_ == SEQUENTIAL_SCHEDULE) {
|
||||
initializeSolver (queryVars);
|
||||
runNeapolitanSolver();
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
if (nodes_[i]->hasEvidence()) {
|
||||
BpNode* v = static_cast<BpNode*> (nodes_[i]);
|
||||
addEvidence (v);
|
||||
vector<BpNode*> parents = cast (v->getParents());
|
||||
for (unsigned int i = 0; i < parents.size(); i++) {
|
||||
if (!parents[i]->hasEvidence()) {
|
||||
sendLambdaMessage (v, parents[i]);
|
||||
}
|
||||
}
|
||||
vector<BpNode*> childs = cast (v->getChilds());
|
||||
for (unsigned int i = 0; i < childs.size(); i++) {
|
||||
sendPiMessage (v, childs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (schedule_ == PARALLEL_SCHEDULE) {
|
||||
BpNode::enableParallelSchedule();
|
||||
initializeSolver (queryVars);
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
if (nodes_[i]->hasEvidence()) {
|
||||
addEvidence (static_cast<BpNode*> (nodes_[i]));
|
||||
}
|
||||
}
|
||||
runIterativeBpSolver();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::printCurrentStatus (void)
|
||||
{
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
printCurrentStatusOf (static_cast<BpNode*> (nodes_[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::printCurrentStatusOf (BpNode* x)
|
||||
{
|
||||
vector<BpNode*> childs = cast (x->getChilds());
|
||||
vector<string> domain = x->getDomain();
|
||||
|
||||
cout << left;
|
||||
cout << setw (10) << "domain" ;
|
||||
cout << setw (20) << "π(" + x->getVariableName() + ")" ;
|
||||
cout << setw (20) << "λ(" + x->getVariableName() + ")" ;
|
||||
cout << setw (16) << "belief" ;
|
||||
cout << endl;
|
||||
|
||||
cout << "--------------------------------" ;
|
||||
cout << "--------------------------------" ;
|
||||
cout << endl;
|
||||
|
||||
double* piValues = x->getPiValues();
|
||||
double* lambdaValues = x->getLambdaValues();
|
||||
double* beliefs = x->getBeliefs();
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
cout << setw (10) << domain[xi];
|
||||
cout << setw (19) << piValues[xi];
|
||||
cout << setw (19) << lambdaValues[xi];
|
||||
cout.precision (PRECISION_);
|
||||
cout << setw (16) << beliefs[xi];
|
||||
cout << endl;
|
||||
}
|
||||
cout << endl;
|
||||
if (childs.size() > 0) {
|
||||
string s = "(" + x->getVariableName() + ")" ;
|
||||
for (unsigned int j = 0; j < childs.size(); j++) {
|
||||
cout << setw (10) << "domain" ;
|
||||
cout << setw (28) << "π" + childs[j]->getVariableName() + s;
|
||||
cout << setw (28) << "λ" + childs[j]->getVariableName() + s;
|
||||
cout << endl;
|
||||
cout << "--------------------------------" ;
|
||||
cout << "--------------------------------" ;
|
||||
cout << endl;
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
cout << setw (10) << domain[xi];
|
||||
cout.precision (PRECISION_);
|
||||
cout << setw (27) << x->getPiMessage(childs[j], xi);
|
||||
cout.precision (PRECISION_);
|
||||
cout << setw (27) << x->getLambdaMessage(childs[j], xi);
|
||||
cout << endl;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::printBeliefs (void)
|
||||
{
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
BpNode* x = static_cast<BpNode*> (nodes_[i]);
|
||||
vector<string> domain = x->getDomain();
|
||||
cout << setw (20) << left << x->getVariableName() ;
|
||||
cout << setw (26) << "belief" ;
|
||||
cout << endl;
|
||||
cout << "--------------------------------------" ;
|
||||
cout << endl;
|
||||
double* beliefs = x->getBeliefs();
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
cout << setw (20) << domain[xi];
|
||||
cout.precision (PRECISION_);
|
||||
cout << setw (26) << beliefs[xi];
|
||||
cout << endl;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<double>
|
||||
BpNetwork::getBeliefs (void)
|
||||
{
|
||||
return getBeliefs (queryNode_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<double>
|
||||
BpNetwork::getBeliefs (BpNode* x)
|
||||
{
|
||||
double* beliefs = x->getBeliefs();
|
||||
vector<double> beliefsVec;
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
beliefsVec.push_back (beliefs[xi]);
|
||||
}
|
||||
return beliefsVec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::initializeSolver (vector<BayesianNode*> queryVars)
|
||||
{
|
||||
if (DL_ >= 1) {
|
||||
cout << "Initializing solver" << endl;
|
||||
if (schedule_ == SEQUENTIAL_SCHEDULE) {
|
||||
cout << "-> schedule = sequential" << endl;
|
||||
} else {
|
||||
cout << "-> schedule = parallel" << endl;
|
||||
}
|
||||
cout << "-> max iters = " << maxIter_ << endl;
|
||||
cout << "-> stable threashold = " << stableThreashold_ << endl;
|
||||
cout << "-> query vars = " ;
|
||||
for (unsigned int i = 0; i < queryVars.size(); i++) {
|
||||
cout << queryVars[i]->getVariableName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
nIter_ = 0;
|
||||
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
BpNode* node = static_cast<BpNode*> (nodes_[i]);
|
||||
node->allocateMemory();
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
BpNode* x = static_cast<BpNode*> (nodes_[i]);
|
||||
|
||||
double* piValues = x->getPiValues();
|
||||
double* lambdaValues = x->getLambdaValues();
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
piValues[xi] = 1.0;
|
||||
lambdaValues[xi] = 1.0;
|
||||
}
|
||||
|
||||
vector<BpNode*> xChilds = cast (x->getChilds());
|
||||
for (unsigned int j = 0; j < xChilds.size(); j++) {
|
||||
double* piMessages = x->getPiMessages (xChilds[j]);
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
piMessages[xi] = 1.0;
|
||||
//x->setPiMessage (xChilds[j], xi, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
vector<BpNode*> xParents = cast (x->getParents());
|
||||
for (unsigned int j = 0; j < xParents.size(); j++) {
|
||||
double* lambdaMessages = xParents[j]->getLambdaMessages (x);
|
||||
for (int xi = 0; xi < xParents[j]->getDomainSize(); xi++) {
|
||||
lambdaMessages[xi] = 1.0;
|
||||
//xParents[j]->setLambdaMessage (x, xi, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
BpNode* x = static_cast<BpNode*> (nodes_[i]);
|
||||
x->normalizeMessages();
|
||||
}
|
||||
printCurrentStatus();
|
||||
|
||||
|
||||
vector<BpNode*> roots = cast (getRootNodes());
|
||||
for (unsigned int i = 0; i < roots.size(); i++) {
|
||||
double* params = roots[i]->getParameters();
|
||||
double* piValues = roots[i]->getPiValues();
|
||||
for (int ri = 0; ri < roots[i]->getDomainSize(); ri++) {
|
||||
piValues[ri] = params[ri];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::addJunctionNode (vector<BayesianNode*> queryVars)
|
||||
{
|
||||
const string VAR_NAME = "_Jn";
|
||||
int nStates = 1;
|
||||
vector<BayesianNode*> parents;
|
||||
vector<string> domain;
|
||||
for (unsigned int i = 0; i < queryVars.size(); i++) {
|
||||
parents.push_back (queryVars[i]);
|
||||
nStates *= queryVars[i]->getDomainSize();
|
||||
}
|
||||
|
||||
for (int i = 0; i < nStates; i++) {
|
||||
stringstream ss;
|
||||
ss << "_jn" << i;
|
||||
domain.push_back (ss.str()); // FIXME make domain optional
|
||||
}
|
||||
|
||||
int nParams = nStates * nStates;
|
||||
double* params = new double [nParams];
|
||||
for (int i = 0; i < nParams; i++) {
|
||||
int row = i / nStates;
|
||||
int col = i % nStates;
|
||||
if (row == col) {
|
||||
params[i] = 1;
|
||||
} else {
|
||||
params[i] = 0;
|
||||
}
|
||||
}
|
||||
addNode (VAR_NAME, parents, params, nParams, domain);
|
||||
queryNode_ = static_cast<BpNode*> (getNode (VAR_NAME));
|
||||
printNetwork();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::addEvidence (BpNode* v)
|
||||
{
|
||||
if (DL_ >= 1) {
|
||||
cout << "Adding evidence: node " ;
|
||||
cout << "`" << v->getVariableName() << "' was instantiated as " ;
|
||||
cout << "`" << v->getDomain()[v->getEvidence()] << "'" ;
|
||||
cout << endl;
|
||||
}
|
||||
double* piValues = v->getPiValues();
|
||||
double* lambdaValues = v->getLambdaValues();
|
||||
for (int vi = 0; vi < v->getDomainSize(); vi++) {
|
||||
if (vi == v->getEvidence()) {
|
||||
piValues[vi] = 1.0;
|
||||
lambdaValues[vi] = 1.0;
|
||||
} else {
|
||||
piValues[vi] = 0.0;
|
||||
lambdaValues[vi] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::runNeapolitanSolver (void)
|
||||
{
|
||||
vector<BpNode*> roots = cast (getRootNodes());
|
||||
for (unsigned int i = 0; i < roots.size(); i++) {
|
||||
vector<BpNode*> childs = cast (roots[i]->getChilds());
|
||||
for (unsigned int j = 0; j < childs.size(); j++) {
|
||||
sendPiMessage (roots[i], static_cast<BpNode*> (childs[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::sendPiMessage (BpNode* z, BpNode* x)
|
||||
{
|
||||
nIter_ ++;
|
||||
if (!(maxIter_ == -1 || nIter_ < maxIter_)) {
|
||||
cout << "the maximum number of iterations was achieved, terminating..." ;
|
||||
cout << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (DL_ >= 1) {
|
||||
cout << "π message " << z->getVariableName();
|
||||
cout << " --> " << x->getVariableName() << endl;
|
||||
}
|
||||
|
||||
updatePiMessages(z, x);
|
||||
|
||||
if (!x->hasEvidence()) {
|
||||
updatePiValues (x);
|
||||
vector<BpNode*> xChilds = cast (x->getChilds());
|
||||
for (unsigned int i = 0; i < xChilds.size(); i++) {
|
||||
sendPiMessage (x, xChilds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool isAllOnes = true;
|
||||
double* lambdaValues = x->getLambdaValues();
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
if (lambdaValues[xi] != 1.0) {
|
||||
isAllOnes = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAllOnes) {
|
||||
vector<BpNode*> xParents = cast (x->getParents());
|
||||
for (unsigned int i = 0; i < xParents.size(); i++) {
|
||||
if (xParents[i] != z && !xParents[i]->hasEvidence()) {
|
||||
sendLambdaMessage (x, xParents[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::sendLambdaMessage (BpNode* y, BpNode* x)
|
||||
{
|
||||
nIter_ ++;
|
||||
if (!(maxIter_ == -1 || nIter_ < maxIter_)) {
|
||||
cout << "the maximum number of iterations was achieved, terminating..." ;
|
||||
cout << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (DL_ >= 1) {
|
||||
cout << "λ message " << y->getVariableName();
|
||||
cout << " --> " << x->getVariableName() << endl;
|
||||
}
|
||||
|
||||
updateLambdaMessages (x, y);
|
||||
updateLambdaValues (x);
|
||||
|
||||
vector<BpNode*> xParents = cast (x->getParents());
|
||||
for (unsigned int i = 0; i < xParents.size(); i++) {
|
||||
if (!xParents[i]->hasEvidence()) {
|
||||
sendLambdaMessage (x, xParents[i]);
|
||||
}
|
||||
}
|
||||
|
||||
vector<BpNode*> xChilds = cast (x->getChilds());
|
||||
for (unsigned int i = 0; i < xChilds.size(); i++) {
|
||||
if (xChilds[i] != y) {
|
||||
sendPiMessage (x, xChilds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::updatePiValues (BpNode* x)
|
||||
{
|
||||
// π(Xi)
|
||||
vector<BpNode*> parents = cast (x->getParents());
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
stringstream calcs1;
|
||||
stringstream calcs2;
|
||||
if (DL_ >= 2) {
|
||||
calcs1 << "π("<< x->getDomain()[xi] << ")" << endl << "= " ;
|
||||
}
|
||||
double sum = 0.0;
|
||||
vector<pair<int, int> > constraints;
|
||||
vector<CptEntry> entries = x->getCptEntriesOfRow (xi);
|
||||
for (unsigned int k = 0; k < entries.size(); k++) {
|
||||
double prod = x->getProbability (entries[k]);
|
||||
if (DL_ >= 2) {
|
||||
if (k != 0) calcs1 << endl << "+ " ;
|
||||
calcs1 << x->entryToString (entries[k]);
|
||||
if (DL_ >= 3) {
|
||||
(k == 0) ? calcs2 << "(" << prod : calcs2 << endl << "+ (" << prod;
|
||||
}
|
||||
}
|
||||
vector<int> insts = entries[k].getDomainInstantiations();
|
||||
for (unsigned int i = 0; i < parents.size(); i++) {
|
||||
double value = parents[i]->getPiMessage (x, insts[i + 1]);
|
||||
prod *= value;
|
||||
if (DL_ >= 2) {
|
||||
calcs1 << ".π" << x->getVariableName();
|
||||
calcs1 << "(" << parents[i]->getDomain()[insts[i + 1]] << ")";
|
||||
if (DL_ >= 3) calcs2 << "x" << value;
|
||||
}
|
||||
}
|
||||
sum += prod;
|
||||
if (DL_ >= 3) calcs2 << ")";
|
||||
}
|
||||
x->setPiValue (xi, sum);
|
||||
if (DL_ >= 2) {
|
||||
cout << calcs1.str();
|
||||
if (DL_ >= 3) cout << endl << "= " << calcs2.str();
|
||||
cout << " = " << sum << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::updatePiMessages (BpNode* z, BpNode* x)
|
||||
{
|
||||
// πX(Zi)
|
||||
vector<BpNode*> zChilds = cast (z->getChilds());
|
||||
for (int zi = 0; zi < z->getDomainSize(); zi++) {
|
||||
stringstream calcs1;
|
||||
stringstream calcs2;
|
||||
if (DL_ >= 2) {
|
||||
calcs1 << "π" << x->getVariableName();
|
||||
calcs1 << "(" << z->getDomain()[zi] << ") = " ;
|
||||
}
|
||||
double prod = z->getPiValue (zi);
|
||||
if (DL_ >= 2) {
|
||||
calcs1 << "π(" << z->getDomain()[zi] << ")" ;
|
||||
if (DL_ >= 3) calcs2 << prod;
|
||||
}
|
||||
for (unsigned int i = 0; i < zChilds.size(); i++) {
|
||||
if (zChilds[i] != x) {
|
||||
double value = z->getLambdaMessage (zChilds[i], zi);
|
||||
prod *= value;
|
||||
if (DL_ >= 2) {
|
||||
calcs1 << ".λ" << zChilds[i]->getVariableName();
|
||||
calcs1 << "(" << z->getDomain()[zi] + ")" ;
|
||||
if (DL_ >= 3) calcs2 << " x " << value;
|
||||
}
|
||||
}
|
||||
}
|
||||
z->setPiMessage (x, zi, prod);
|
||||
if (DL_ >= 2) {
|
||||
cout << calcs1.str();
|
||||
if (DL_ >= 3) cout << " = " << calcs2.str();
|
||||
cout << " = " << prod << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::updateLambdaValues (BpNode* x)
|
||||
{
|
||||
// λ(Xi)
|
||||
vector<BpNode*> childs = cast (x->getChilds());
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
stringstream calcs1;
|
||||
stringstream calcs2;
|
||||
if (DL_ >= 2) {
|
||||
calcs1 << "λ" << "(" << x->getDomain()[xi] << ") = " ;
|
||||
}
|
||||
double prod = 1.0;
|
||||
for (unsigned int i = 0; i < childs.size(); i++) {
|
||||
double val = x->getLambdaMessage (childs[i], xi);
|
||||
prod *= val;
|
||||
if (DL_ >= 2) {
|
||||
if (i != 0) calcs1 << "." ;
|
||||
calcs1 << "λ" << childs[i]->getVariableName();
|
||||
calcs1 << "(" << x->getDomain()[xi] + ")" ;
|
||||
if (DL_ >= 3) (i == 0) ? calcs2 << val : calcs2 << " x " << val;
|
||||
}
|
||||
}
|
||||
x->setLambdaValue (xi, prod);
|
||||
if (DL_ >= 2) {
|
||||
cout << calcs1.str();
|
||||
if (childs.size() == 0) {
|
||||
cout << 1 << endl;
|
||||
} else {
|
||||
if (DL_ >= 3) cout << " = " << calcs2.str();
|
||||
cout << " = " << prod << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::updateLambdaMessages (BpNode* x, BpNode* y)
|
||||
{
|
||||
// λY(Xi)
|
||||
int parentIndex = y->getIndexOfParent (x) + 1;
|
||||
vector<BpNode*> yParents = cast (y->getParents());
|
||||
for (int xi = 0; xi < x->getDomainSize(); xi++) {
|
||||
stringstream calcs1;
|
||||
stringstream calcs2;
|
||||
if (DL_ >= 2) {
|
||||
calcs1 << "λ" << y->getVariableName() ;
|
||||
calcs1 << "(" << x->getDomain()[xi] << ")" << endl << "= " ;
|
||||
}
|
||||
double outer_sum = 0.0;
|
||||
for (int yi = 0; yi < y->getDomainSize(); yi++) {
|
||||
if (DL_ >= 2) {
|
||||
(yi == 0) ? calcs1 << "[" : calcs1 << endl << "+ [" ;
|
||||
if (DL_ >= 3) {
|
||||
(yi == 0) ? calcs2 << "[" : calcs2 << endl << "+ [" ;
|
||||
}
|
||||
}
|
||||
double inner_sum = 0.0;
|
||||
vector<pair<int, int> > constraints;
|
||||
constraints.push_back (make_pair (0, yi));
|
||||
constraints.push_back (make_pair (parentIndex, xi));
|
||||
vector<CptEntry> entries = y->getCptEntries (constraints);
|
||||
for (unsigned int k = 0; k < entries.size(); k++) {
|
||||
double prod = y->getProbability (entries[k]);
|
||||
if (DL_ >= 2) {
|
||||
if (k != 0) calcs1 << " + " ;
|
||||
calcs1 << y->entryToString (entries[k]);
|
||||
if (DL_ >= 3) {
|
||||
(k == 0) ? calcs2 << "(" << prod : calcs2 << " + (" << prod;
|
||||
}
|
||||
}
|
||||
vector<int> insts = entries[k].getDomainInstantiations();
|
||||
for (unsigned int i = 0; i < yParents.size(); i++) {
|
||||
if (yParents[i] != x) {
|
||||
double val = yParents[i]->getPiMessage (y, insts[i + 1]);
|
||||
prod *= val;
|
||||
if (DL_ >= 2) {
|
||||
calcs1 << ".π" << y->getVariableName();
|
||||
calcs1 << "(" << yParents[i]->getDomain()[insts[i + 1]] << ")" ;
|
||||
if (DL_ >= 3) calcs2 << "x" << val;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
inner_sum += prod;
|
||||
if (DL_ >= 3) {
|
||||
calcs2 << ")" ;
|
||||
}
|
||||
}
|
||||
outer_sum += inner_sum * y->getLambdaValue (yi);
|
||||
if (DL_ >= 2) {
|
||||
calcs1 << "].λ(" << y->getDomain()[yi] << ")";
|
||||
if (DL_ >= 3) calcs2 << "]x" << y->getLambdaValue (yi);
|
||||
}
|
||||
}
|
||||
x->setLambdaMessage (y, xi, outer_sum);
|
||||
if (DL_ >= 2) {
|
||||
cout << calcs1.str();
|
||||
if (DL_ >= 3) cout << endl << "= " << calcs2.str();
|
||||
cout << " = " << outer_sum << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::runIterativeBpSolver()
|
||||
{
|
||||
int nIter = 0;
|
||||
maxIter_ = 100;
|
||||
bool converged = false;
|
||||
while (nIter < maxIter_ && !converged) {
|
||||
if (DL_ >= 1) {
|
||||
cout << endl << endl;
|
||||
cout << "****************************************" ;
|
||||
cout << "****************************************" ;
|
||||
cout << endl;
|
||||
cout << " Iteration " << nIter + 1 << endl;
|
||||
cout << "****************************************" ;
|
||||
cout << "****************************************" ;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
BpNode* x = static_cast<BpNode*>(nodes_[i]);
|
||||
vector<BpNode*> xParents = cast (x->getParents());
|
||||
for (unsigned int j = 0; j < xParents.size(); j++) {
|
||||
//if (!xParents[j]->hasEvidence()) {
|
||||
if (DL_ >= 1) {
|
||||
cout << endl << "λ message " << x->getVariableName();
|
||||
cout << " --> " << xParents[j]->getVariableName() << endl;
|
||||
}
|
||||
updateLambdaMessages (xParents[j], x);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
BpNode* x = static_cast<BpNode*>(nodes_[i]);
|
||||
vector<BpNode*> xChilds = cast (x->getChilds());
|
||||
for (unsigned int j = 0; j < xChilds.size(); j++) {
|
||||
if (DL_ >= 1) {
|
||||
cout << endl << "π message " << x->getVariableName();
|
||||
cout << " --> " << xChilds[j]->getVariableName() << endl;
|
||||
}
|
||||
updatePiMessages (x, xChilds[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
BpNode* x = static_cast<BpNode*>(nodes_[i]);
|
||||
vector<BpNode*> xChilds = cast (x->getChilds());
|
||||
for (unsigned int j = 0; j < xChilds.size(); j++) {
|
||||
if (DL_ >= 1) {
|
||||
cout << "π message " << x->getVariableName();
|
||||
cout << " --> " << xChilds[j]->getVariableName() << endl;
|
||||
}
|
||||
updatePiMessages (x, xChilds[j]);
|
||||
}
|
||||
vector<BpNode*> xParents = cast (x->getParents());
|
||||
for (unsigned int j = 0; j < xParents.size(); j++) {
|
||||
//if (!xParents[j]->hasEvidence()) {
|
||||
if (DL_ >= 1) {
|
||||
cout << "λ message " << x->getVariableName();
|
||||
cout << " --> " << xParents[j]->getVariableName() << endl;
|
||||
}
|
||||
updateLambdaMessages (xParents[j], x);
|
||||
//}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
BpNode* x = static_cast<BpNode*> (nodes_[i]);
|
||||
//cout << endl << "SWAPING MESSAGES FOR " << x->getVariableName() << ":" ;
|
||||
//cout << endl << endl;
|
||||
//printCurrentStatusOf (x);
|
||||
x->swapMessages();
|
||||
x->normalizeMessages();
|
||||
//cout << endl << "messages swaped " << endl;
|
||||
//printCurrentStatusOf (x);
|
||||
}
|
||||
|
||||
converged = true;
|
||||
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
BpNode* x = static_cast<BpNode*>(nodes_[i]);
|
||||
if (DL_ >= 1) {
|
||||
cout << endl << "var " << x->getVariableName() << ":" << endl;
|
||||
}
|
||||
//if (!x->hasEvidence()) {
|
||||
updatePiValues (x);
|
||||
updateLambdaValues (x);
|
||||
double change = x->getBeliefChange();
|
||||
if (DL_ >= 1) {
|
||||
cout << "belief change = " << change << endl;
|
||||
}
|
||||
if (change > stableThreashold_) {
|
||||
converged = false;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
if (converged) {
|
||||
// converged = false;
|
||||
}
|
||||
if (DL_ >= 2) {
|
||||
cout << endl;
|
||||
printCurrentStatus();
|
||||
}
|
||||
nIter++;
|
||||
}
|
||||
|
||||
if (DL_ >= 1) {
|
||||
cout << endl;
|
||||
if (converged) {
|
||||
cout << "Iterative belief propagation converged in " ;
|
||||
cout << nIter << " iterations" << endl;
|
||||
} else {
|
||||
cout << "Iterative belief propagation converged didn't converge" ;
|
||||
cout << endl;
|
||||
}
|
||||
if (DL_ == 1) {
|
||||
cout << endl;
|
||||
printBeliefs();
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::addNode (string varName,
|
||||
vector<BayesianNode*> parents,
|
||||
int evidence,
|
||||
int distId)
|
||||
{
|
||||
for (unsigned int i = 0; i < dists_.size(); i++) {
|
||||
if (dists_[i]->id == distId) {
|
||||
BpNode* node = new BpNode (varName, parents, dists_[i], evidence);
|
||||
nodes_.push_back (node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNetwork::addNode (string varName,
|
||||
vector<BayesianNode*> parents,
|
||||
double* params,
|
||||
int nParams,
|
||||
vector<string> domain)
|
||||
{
|
||||
Distribution* dist = new Distribution (params, nParams, domain);
|
||||
BpNode* node = new BpNode (varName, parents, dist);
|
||||
dists_.push_back (dist);
|
||||
nodes_.push_back (node);
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<BpNode*>
|
||||
BpNetwork::cast (vector<BayesianNode*> nodes)
|
||||
{
|
||||
vector<BpNode*> castedNodes (nodes.size());
|
||||
for (unsigned int i = 0; i < nodes.size(); i++) {
|
||||
castedNodes[i] = static_cast<BpNode*> (nodes[i]);
|
||||
}
|
||||
return castedNodes;
|
||||
}
|
||||
|
66
packages/CLPBN/clpbn/bp/BpNetwork.h
Normal file
66
packages/CLPBN/clpbn/bp/BpNetwork.h
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef BP_BP_NETWORK_H
|
||||
#define BP_BP_NETWORK_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "BayesianNetwork.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BpNode;
|
||||
|
||||
enum Schedule
|
||||
{
|
||||
SEQUENTIAL_SCHEDULE,
|
||||
PARALLEL_SCHEDULE
|
||||
};
|
||||
|
||||
class BpNetwork : public BayesianNetwork
|
||||
{
|
||||
public:
|
||||
// constructs
|
||||
BpNetwork (void);
|
||||
// destruct
|
||||
~BpNetwork (void);
|
||||
// methods
|
||||
void setSolverParameters (Schedule, int, double);
|
||||
void runSolver (BayesianNode* queryVar);
|
||||
void runSolver (vector<BayesianNode*>);
|
||||
void printCurrentStatus (void);
|
||||
void printCurrentStatusOf (BpNode*);
|
||||
void printBeliefs (void);
|
||||
vector<double> getBeliefs (void);
|
||||
vector<double> getBeliefs (BpNode*);
|
||||
|
||||
private:
|
||||
BpNetwork (const BpNetwork&); // disallow copy
|
||||
void operator= (const BpNetwork&); // disallow assign
|
||||
// methods
|
||||
void initializeSolver (vector<BayesianNode*>);
|
||||
void addJunctionNode (vector<BayesianNode*>);
|
||||
void addEvidence (BpNode*);
|
||||
void runNeapolitanSolver (void);
|
||||
void sendLambdaMessage (BpNode*, BpNode*);
|
||||
void sendPiMessage (BpNode*, BpNode*);
|
||||
void updatePiValues (BpNode*);
|
||||
void updatePiMessages (BpNode*, BpNode*);
|
||||
void updateLambdaValues (BpNode*);
|
||||
void updateLambdaMessages (BpNode*, BpNode*);
|
||||
void runIterativeBpSolver (void);
|
||||
void addNode (string, vector<BayesianNode*>, int, int);
|
||||
void addNode (string, vector<BayesianNode*>,
|
||||
double*, int, vector<string>);
|
||||
vector<BpNode*> cast (vector<BayesianNode*>);
|
||||
// members
|
||||
Schedule schedule_;
|
||||
int nIter_;
|
||||
int maxIter_;
|
||||
double stableThreashold_;
|
||||
BpNode* queryNode_;
|
||||
static const int DL_ = 3;
|
||||
static const int PRECISION_ = 10;
|
||||
};
|
||||
|
||||
#endif // BP_BP_NETWORK_H
|
||||
|
321
packages/CLPBN/clpbn/bp/BpNode.cpp
Normal file
321
packages/CLPBN/clpbn/bp/BpNode.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
#include "BpNode.h"
|
||||
|
||||
|
||||
bool BpNode::parallelSchedule_ = false;
|
||||
|
||||
BpNode::BpNode (string varName,
|
||||
vector<BayesianNode*> parents,
|
||||
Distribution* dist,
|
||||
int evidence) : BayesianNode (varName, parents, dist, evidence)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
BpNode::~BpNode (void)
|
||||
{
|
||||
delete [] piValues_;
|
||||
delete [] lambdaValues_;
|
||||
delete [] oldBeliefs_;
|
||||
map<BpNode*, double*>::iterator iter;
|
||||
for (iter = lambdaMessages_.begin(); iter != lambdaMessages_.end(); ++iter) {
|
||||
delete [] iter->second;
|
||||
}
|
||||
for (iter = piMessages_.begin(); iter != piMessages_.end(); ++iter) {
|
||||
delete [] iter->second;
|
||||
}
|
||||
// FIXME delete new messages
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNode::enableParallelSchedule (void)
|
||||
{
|
||||
parallelSchedule_ = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNode::allocateMemory (void)
|
||||
{
|
||||
// FIXME do i need this !?
|
||||
int domainSize = getDomainSize();
|
||||
piValues_ = new double [domainSize];
|
||||
lambdaValues_ = new double [domainSize];
|
||||
if (parallelSchedule_) {
|
||||
newPiMessages_ = new map<BpNode*, double*>;
|
||||
newLambdaMessages_ = new map<BpNode*, double*>;
|
||||
}
|
||||
oldBeliefs_ = 0;
|
||||
vector <BayesianNode*> childs = getChilds();
|
||||
for (unsigned int i = 0; i < childs.size(); i++) {
|
||||
BpNode* child = static_cast<BpNode*> (childs[i]);
|
||||
piMessages_.insert (make_pair (child, new double [domainSize]));
|
||||
lambdaMessages_.insert (make_pair (child, new double [domainSize]));
|
||||
if (parallelSchedule_) {
|
||||
newPiMessages_->insert (make_pair (child, new double [domainSize]));
|
||||
newLambdaMessages_->insert (make_pair (child, new double [domainSize]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
double*
|
||||
BpNode::getPiValues (void) const
|
||||
{
|
||||
return piValues_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
BpNode::getPiValue (int index) const
|
||||
{
|
||||
const int c = getDomainSize();
|
||||
assert (index >=0 && index < c);
|
||||
return piValues_[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNode::setPiValue (int index, double value)
|
||||
{
|
||||
const int c = getDomainSize();
|
||||
assert (index >=0 && index < c);
|
||||
piValues_[index] = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double*
|
||||
BpNode::getLambdaValues (void) const
|
||||
{
|
||||
return lambdaValues_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
BpNode::getLambdaValue (int index) const
|
||||
{
|
||||
const int c = getDomainSize();
|
||||
assert (index >=0 && index < c);
|
||||
return lambdaValues_[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNode::setLambdaValue (int index, double value)
|
||||
{
|
||||
const int c = getDomainSize();
|
||||
assert (index >=0 && index < c);
|
||||
lambdaValues_[index] = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double*
|
||||
BpNode::getPiMessages (BpNode* node) const
|
||||
{
|
||||
assert (node);
|
||||
map<BpNode*, double*>::const_iterator iter = piMessages_.find (node);
|
||||
assert (iter != piMessages_.end());
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
BpNode::getPiMessage (BpNode* node, int index) const
|
||||
{
|
||||
assert (node);
|
||||
const int c = getDomainSize();
|
||||
assert (index >=0 && index < c);
|
||||
map<BpNode*, double*>::const_iterator iter = piMessages_.find (node);
|
||||
assert (iter != piMessages_.end());
|
||||
return iter->second[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNode::setPiMessage (BpNode* node, int index, double probability)
|
||||
{
|
||||
assert (node);
|
||||
const int c = getDomainSize();
|
||||
assert (index >=0 && index < c);
|
||||
map<BpNode*, double*>::const_iterator iter;
|
||||
if (parallelSchedule_) {
|
||||
// cerr << "set_pi_message" << endl;
|
||||
iter = newPiMessages_->find (node);
|
||||
assert (iter != newPiMessages_->end());
|
||||
} else {
|
||||
iter = piMessages_.find (node);
|
||||
assert (iter != piMessages_.end());
|
||||
}
|
||||
iter->second[index] = probability;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double*
|
||||
BpNode::getLambdaMessages (BpNode* node) const
|
||||
{
|
||||
assert (node);
|
||||
map<BpNode*, double*>::const_iterator iter = lambdaMessages_.find (node);
|
||||
assert (iter != piMessages_.end());
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
BpNode::getLambdaMessage (BpNode* node, int index) const
|
||||
{
|
||||
assert (node);
|
||||
const int c = getDomainSize();
|
||||
assert (index >=0 && index < c);
|
||||
map<BpNode*, double*>::const_iterator iter = lambdaMessages_.find (node);
|
||||
assert (iter != piMessages_.end());
|
||||
return iter->second[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNode::setLambdaMessage (BpNode* node, int index, double probability)
|
||||
{
|
||||
assert (node);
|
||||
const int c = getDomainSize();
|
||||
assert (index >=0 && index < c);
|
||||
map<BpNode*, double*>::const_iterator iter;
|
||||
if (parallelSchedule_) {
|
||||
//cerr << "set_lambda_message" << endl;
|
||||
iter = newLambdaMessages_->find (node);
|
||||
assert (iter != newLambdaMessages_->end());
|
||||
} else {
|
||||
iter = lambdaMessages_.find (node);
|
||||
assert (iter != lambdaMessages_.end());
|
||||
}
|
||||
iter->second[index] = probability;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double*
|
||||
BpNode::getBeliefs (void)
|
||||
{
|
||||
double sum = 0.0;
|
||||
double* beliefs = new double [getDomainSize()];
|
||||
for (int xi = 0; xi < getDomainSize(); xi++) {
|
||||
double prod = piValues_[xi] * lambdaValues_[xi];
|
||||
beliefs[xi] = prod;
|
||||
sum += prod;
|
||||
}
|
||||
// normalize the beliefs
|
||||
for (int xi = 0; xi < getDomainSize(); xi++) {
|
||||
beliefs[xi] /= sum;
|
||||
}
|
||||
return beliefs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
BpNode::getBeliefChange (void)
|
||||
{
|
||||
double change = 0.0;
|
||||
if (!oldBeliefs_) {
|
||||
oldBeliefs_ = getBeliefs();
|
||||
change = MAX_CHANGE_;
|
||||
} else {
|
||||
double* currentBeliefs = getBeliefs();
|
||||
for (int xi = 0; xi < getDomainSize(); xi++) {
|
||||
change += abs (currentBeliefs[xi] - oldBeliefs_[xi]);
|
||||
}
|
||||
oldBeliefs_ = currentBeliefs;
|
||||
}
|
||||
//FIXME memory leak
|
||||
return change;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNode::normalizeMessages (void)
|
||||
{
|
||||
map<BpNode*, double*>::iterator iter;
|
||||
|
||||
iter = lambdaMessages_.begin();
|
||||
while (iter != lambdaMessages_.end()) {
|
||||
double* v = iter->second;
|
||||
double sum = 0.0;
|
||||
for (int xi = 0; xi < getDomainSize(); xi++) {
|
||||
sum += v[xi];
|
||||
}
|
||||
for (int xi = 0; xi < getDomainSize(); xi++) {
|
||||
v[xi] /= sum;
|
||||
}
|
||||
iter ++;
|
||||
}
|
||||
|
||||
iter = piMessages_.begin();
|
||||
while (iter != piMessages_.end()) {
|
||||
double* v = iter->second;
|
||||
double sum = 0.0;
|
||||
for (int xi = 0; xi < getDomainSize(); xi++) {
|
||||
sum += v[xi];
|
||||
}
|
||||
for (int xi = 0; xi < getDomainSize(); xi++) {
|
||||
v[xi] /= sum;
|
||||
}
|
||||
iter ++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNode::swapMessages (void)
|
||||
{
|
||||
//FIXME fast way to do this
|
||||
map<BpNode*, double*>::iterator iter1;
|
||||
map<BpNode*, double*>::iterator iter2;
|
||||
|
||||
iter1 = lambdaMessages_.begin();
|
||||
iter2 = newLambdaMessages_->begin();
|
||||
while (iter1 != lambdaMessages_.end()) {
|
||||
double* v1 = iter1->second;
|
||||
double* v2 = iter2->second;
|
||||
for (int xi = 0; xi < getDomainSize(); xi++) {
|
||||
//v1[xi] = v2[xi];
|
||||
v1[xi] = (v1[xi] + v2[xi]) / 2;
|
||||
}
|
||||
iter1 ++;
|
||||
iter2 ++;
|
||||
}
|
||||
|
||||
iter1 = piMessages_.begin();
|
||||
iter2 = newPiMessages_->begin();
|
||||
while (iter1 != piMessages_.end()) {
|
||||
double* v1 = iter1->second;
|
||||
double* v2 = iter2->second;
|
||||
for (int xi = 0; xi < getDomainSize(); xi++) {
|
||||
//v1[xi] = v2[xi];
|
||||
v1[xi] = (v1[xi] + v2[xi]) / 2;
|
||||
}
|
||||
iter1 ++;
|
||||
iter2 ++;
|
||||
}
|
||||
}
|
||||
|
56
packages/CLPBN/clpbn/bp/BpNode.h
Normal file
56
packages/CLPBN/clpbn/bp/BpNode.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef BP_BP_NODE_H
|
||||
#define BP_BP_NODE_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
#include "BayesianNode.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BpNode : public BayesianNode
|
||||
{
|
||||
public:
|
||||
// constructs
|
||||
BpNode (string, vector<BayesianNode*>, Distribution* dist, int = -1);
|
||||
// destruct
|
||||
~BpNode (void);
|
||||
// methods
|
||||
static void enableParallelSchedule (void);
|
||||
void allocateMemory (void);
|
||||
double* getPiValues (void) const;
|
||||
double getPiValue (int) const;
|
||||
void setPiValue (int, double);
|
||||
double* getLambdaValues (void) const;
|
||||
double getLambdaValue (int) const;
|
||||
void setLambdaValue (int, double);
|
||||
double* getPiMessages (BpNode*) const;
|
||||
double getPiMessage (BpNode*, int) const;
|
||||
void setPiMessage (BpNode*, int, double);
|
||||
double* getLambdaMessages (BpNode*) const;
|
||||
double getLambdaMessage (BpNode*, int) const;
|
||||
void setLambdaMessage (BpNode*, int, double);
|
||||
double* getBeliefs (void);
|
||||
double getBeliefChange (void);
|
||||
void normalizeMessages (void);
|
||||
void swapMessages (void);
|
||||
|
||||
private:
|
||||
BpNode (const BpNode&); // disallow copy
|
||||
void operator= (const BpNode&); // disallow assign
|
||||
// members
|
||||
double* lambdaValues_;
|
||||
double* piValues_;
|
||||
map<BpNode*, double*> piMessages_;
|
||||
map<BpNode*, double*> lambdaMessages_;
|
||||
map<BpNode*, double*>* newPiMessages_;
|
||||
map<BpNode*, double*>* newLambdaMessages_;
|
||||
double* oldBeliefs_;
|
||||
static bool parallelSchedule_;
|
||||
static const double MAX_CHANGE_ = 1.0;
|
||||
};
|
||||
|
||||
#endif // BP_BP_NODE_H
|
||||
|
38
packages/CLPBN/clpbn/bp/CptEntry.cpp
Normal file
38
packages/CLPBN/clpbn/bp/CptEntry.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "CptEntry.h"
|
||||
|
||||
CptEntry::CptEntry (int cptIndex, vector<int> instantiations)
|
||||
{
|
||||
cptIndex_ = cptIndex;
|
||||
instantiations_ = instantiations;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
CptEntry::getCptIndex (void) const
|
||||
{
|
||||
return cptIndex_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<int>
|
||||
CptEntry::getDomainInstantiations (void) const
|
||||
{
|
||||
return instantiations_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
CptEntry::matchConstraints (const vector<pair<int,int> >& constraints) const
|
||||
{
|
||||
for (unsigned int j = 0; j < constraints.size(); j++) {
|
||||
int index = constraints[j].first;
|
||||
if (instantiations_[index] != constraints[j].second) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
23
packages/CLPBN/clpbn/bp/CptEntry.h
Normal file
23
packages/CLPBN/clpbn/bp/CptEntry.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef CPT_ENTRY_H
|
||||
#define CPT_ENTRY_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CptEntry
|
||||
{
|
||||
public:
|
||||
// constructs
|
||||
CptEntry (int, vector<int>);
|
||||
// methods
|
||||
int getCptIndex (void) const;
|
||||
vector<int> getDomainInstantiations (void) const;
|
||||
bool matchConstraints (const vector<pair<int,int> >&) const;
|
||||
private:
|
||||
// members
|
||||
int cptIndex_;
|
||||
vector<int> instantiations_;
|
||||
};
|
||||
|
||||
#endif // CPT_ENTRY_H
|
40
packages/CLPBN/clpbn/bp/Distribution.cpp
Normal file
40
packages/CLPBN/clpbn/bp/Distribution.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <Distribution.h>
|
||||
|
||||
Distribution::Distribution (int id,
|
||||
double* params,
|
||||
int nParams,
|
||||
vector<string> domain)
|
||||
{
|
||||
this->id = id;
|
||||
this->params = params;
|
||||
this->nParams = nParams;
|
||||
this->domain = domain;
|
||||
}
|
||||
|
||||
|
||||
Distribution::Distribution (double* params,
|
||||
int nParams,
|
||||
vector<string> domain)
|
||||
{
|
||||
this->id = -1;
|
||||
this->params = params;
|
||||
this->nParams = nParams;
|
||||
this->domain = domain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Distribution::~Distribution()
|
||||
{
|
||||
delete params;
|
||||
for (unsigned int i = 0; i < cptEntries.size(); i++) {
|
||||
delete cptEntries[i];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
24
packages/CLPBN/clpbn/bp/Distribution.h
Normal file
24
packages/CLPBN/clpbn/bp/Distribution.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef DISTRIBUTION_H
|
||||
#define DISTRIBUTION_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CptEntry;
|
||||
|
||||
class Distribution
|
||||
{
|
||||
public:
|
||||
Distribution (int, double*, int, vector<string>);
|
||||
Distribution (double*, int, vector<string>);
|
||||
int id;
|
||||
double* params;
|
||||
int nParams;
|
||||
vector<string> domain;
|
||||
int* offsets;
|
||||
};
|
||||
|
||||
#endif // DISTRIBUTION
|
||||
|
125
packages/CLPBN/clpbn/bp/Horus.cpp
Normal file
125
packages/CLPBN/clpbn/bp/Horus.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <Yap/YapInterface.h>
|
||||
|
||||
#include <BayesianNetwork.h>
|
||||
#include <BayesianNode.h>
|
||||
#include <BpNetwork.h>
|
||||
#include <BpNode.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
int addVariables (BayesianNetwork&, YAP_Term, int);
|
||||
int addDistributions (BayesianNetwork&, YAP_Term, int);
|
||||
|
||||
int createNetwork (void)
|
||||
{
|
||||
BayesianNetwork* bn = new BpNetwork();
|
||||
addDistributions (*bn, YAP_ARG3, (int) YAP_IntOfTerm (YAP_ARG4));
|
||||
addVariables (*bn, YAP_ARG1, (int) YAP_IntOfTerm (YAP_ARG2));
|
||||
YAP_Int p = (YAP_Int) (bn);
|
||||
return YAP_Unify (YAP_MkIntTerm (p), YAP_ARG5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int addVariables (BayesianNetwork& bn, YAP_Term varList, int nVars)
|
||||
{
|
||||
for (int i = 0; i < nVars; i++) {
|
||||
YAP_Term var = YAP_HeadOfTerm (varList);
|
||||
int varId = (int) YAP_IntOfTerm (YAP_ArgOfTerm (1, var));
|
||||
int distId = (int) YAP_IntOfTerm (YAP_ArgOfTerm (2, var));
|
||||
YAP_Term parentsList = YAP_ArgOfTerm (3, var);
|
||||
int nParents = (int) YAP_IntOfTerm (YAP_ArgOfTerm (4, var));
|
||||
vector<BayesianNode*> parents;
|
||||
for (int j = 0; j < nParents; j++) {
|
||||
int parentId = (int) YAP_IntOfTerm (YAP_HeadOfTerm (parentsList));
|
||||
stringstream parentName;
|
||||
parentName << parentId;
|
||||
parents.push_back (bn.getNode (parentName.str()));
|
||||
parentsList = YAP_TailOfTerm (parentsList);
|
||||
}
|
||||
stringstream nodeName;
|
||||
nodeName << varId;
|
||||
int evidence = (int) YAP_IntOfTerm (YAP_ArgOfTerm (5, var));
|
||||
bn.addNode (nodeName.str(), parents, evidence, distId);
|
||||
varList = YAP_TailOfTerm (varList);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int addDistributions (BayesianNetwork& bn, YAP_Term distList, int nDists)
|
||||
{
|
||||
for (int i = 0; i < nDists; i++) {
|
||||
YAP_Term dist = YAP_HeadOfTerm (distList);
|
||||
int distId = (int) YAP_IntOfTerm (YAP_ArgOfTerm (1, dist));
|
||||
YAP_Term domainList = YAP_ArgOfTerm (2, dist);
|
||||
int domainSize = (int) YAP_IntOfTerm (YAP_ArgOfTerm (3, dist));
|
||||
vector<string> domain (domainSize);
|
||||
for (int j = 0; j < domainSize; j++) {
|
||||
YAP_Atom atom = YAP_AtomOfTerm (YAP_HeadOfTerm (domainList));
|
||||
domain[j] = (char*) YAP_AtomName (atom);;
|
||||
domainList = YAP_TailOfTerm (domainList);
|
||||
}
|
||||
YAP_Term paramsList = YAP_ArgOfTerm (4, dist);
|
||||
int nParams = (int) YAP_IntOfTerm (YAP_ArgOfTerm (5, dist));
|
||||
double* params = new double [nParams];
|
||||
for (int j = 0; j < nParams; j++) {
|
||||
params[j] = (double) YAP_FloatOfTerm (YAP_HeadOfTerm (paramsList));
|
||||
paramsList = YAP_TailOfTerm (paramsList);
|
||||
}
|
||||
bn.addDistribution (distId, params, nParams, domain);
|
||||
distList = YAP_TailOfTerm (distList);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int runSolver (void)
|
||||
{
|
||||
BpNetwork* bn = (BpNetwork*) YAP_IntOfTerm (YAP_ARG1);
|
||||
YAP_Term queryVarsList = YAP_ARG2;
|
||||
int nQueryVars = (int) YAP_IntOfTerm (YAP_ARG3);
|
||||
vector<BayesianNode*> queryVars;
|
||||
for (int i = 0; i < nQueryVars; i++) {
|
||||
int queryVarId = (int) YAP_IntOfTerm (YAP_HeadOfTerm (queryVarsList));
|
||||
stringstream queryVarName;
|
||||
queryVarName << queryVarId;
|
||||
queryVars.push_back (bn->getNode (queryVarName.str()));
|
||||
queryVarsList = YAP_TailOfTerm (queryVarsList);
|
||||
}
|
||||
bn->runSolver (queryVars);
|
||||
vector<double> beliefs = bn->getBeliefs();
|
||||
YAP_Term beliefsList = YAP_TermNil();
|
||||
for (int i = beliefs.size() - 1; i >= 0; i--) {
|
||||
YAP_Term belief = YAP_MkFloatTerm (beliefs[i]);
|
||||
beliefsList = YAP_MkPairTerm (belief, beliefsList);
|
||||
}
|
||||
return YAP_Unify (beliefsList, YAP_ARG4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int freeMemory (void)
|
||||
{
|
||||
BpNetwork* bn = (BpNetwork*) YAP_IntOfTerm (YAP_ARG1);
|
||||
delete bn;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C" void init_predicates (void)
|
||||
{
|
||||
YAP_UserCPredicate ("create_network", createNetwork, 5);
|
||||
YAP_UserCPredicate ("run_solver", runSolver, 4);
|
||||
YAP_UserCPredicate ("free_memory", freeMemory, 1);
|
||||
}
|
||||
|
115
packages/CLPBN/clpbn/bp/Makefile
Normal file
115
packages/CLPBN/clpbn/bp/Makefile
Normal file
@ -0,0 +1,115 @@
|
||||
#
|
||||
# default base directory for YAP installation
|
||||
# (EROOT for architecture-dependent files)
|
||||
#
|
||||
GCC = yes
|
||||
prefix = /usr/local
|
||||
exec_prefix = ${prefix}
|
||||
ROOTDIR = $(prefix)
|
||||
EROOTDIR = ${prefix}
|
||||
abs_top_builddir = /home/tiago/yap
|
||||
#
|
||||
# where the binary should be
|
||||
#
|
||||
BINDIR = $(EROOTDIR)/bin
|
||||
#
|
||||
# where YAP should look for libraries
|
||||
#
|
||||
LIBDIR=${exec_prefix}/lib
|
||||
YAPLIBDIR=${exec_prefix}/lib/Yap
|
||||
#
|
||||
#
|
||||
CC=gcc
|
||||
CXX=g++
|
||||
CXXFLAGS= -shared -fPIC -DBP_FREE -O3 -fomit-frame-pointer -Wall -g -O2 $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../../.. -I$(srcdir)/../../../../include
|
||||
#
|
||||
#
|
||||
# You shouldn't need to change what follows.
|
||||
#
|
||||
INSTALL=/usr/bin/install -c
|
||||
INSTALL_DATA=${INSTALL} -m 644
|
||||
INSTALL_PROGRAM=${INSTALL}
|
||||
SHELL=/bin/sh
|
||||
RANLIB=ranlib
|
||||
srcdir=.
|
||||
SO=so
|
||||
#4.1VPATH=.:./OPTYap
|
||||
CWD=$(PWD)
|
||||
|
||||
|
||||
HEADERS = \
|
||||
$(srcdir)/BayesianNetwork.h \
|
||||
$(srcdir)/BayesianNode.h \
|
||||
$(srcdir)/BpNetwork.h \
|
||||
$(srcdir)/BpNode.h \
|
||||
$(srcdir)/Distribution.h \
|
||||
$(srcdir)/CptEntry.h \
|
||||
$(srcdir)/BifInterface.h \
|
||||
$(srcdir)/xmlParser/xmlParser.h
|
||||
|
||||
CPP_SOURCES = \
|
||||
$(srcdir)/BayesianNetwork.cpp \
|
||||
$(srcdir)/BayesianNode.cpp \
|
||||
$(srcdir)/BpNetwork.cpp \
|
||||
$(srcdir)/BpNode.cpp \
|
||||
$(srcdir)/Distribution.cpp \
|
||||
$(srcdir)/CptEntry.cpp \
|
||||
$(srcdir)/Horus.cpp \
|
||||
$(srcdir)/BifInterface.cpp \
|
||||
$(srcdir)/BifTest.cpp \
|
||||
$(srcdir)/xmlParser/xmlParser.cpp
|
||||
|
||||
OBJS = \
|
||||
BayesianNetwork.o \
|
||||
BayesianNode.o \
|
||||
BpNetwork.o \
|
||||
BpNode.o \
|
||||
Distribution.o \
|
||||
CptEntry.o \
|
||||
Horus.o
|
||||
|
||||
BIF_OBJS = \
|
||||
BayesianNetwork.o \
|
||||
BayesianNode.o \
|
||||
BpNetwork.o \
|
||||
BpNode.o \
|
||||
Distribution.o \
|
||||
CptEntry.o \
|
||||
BifInterface.o \
|
||||
BifTest.o \
|
||||
xmlParser/xmlParser.o
|
||||
|
||||
SOBJS=horus.so
|
||||
|
||||
|
||||
all: $(SOBJS) biftest
|
||||
|
||||
# default rule
|
||||
%.o : $(srcdir)/%.cpp
|
||||
$(CXX) -c $(CXXFLAGS) $< -o $@
|
||||
|
||||
horus.so: $(OBJS)
|
||||
g++ -shared -export-dynamic -o horus.so $(OBJS)
|
||||
|
||||
biftest: $(BIF_OBJS)
|
||||
$(CXX) -o biftest $(BIF_OBJS)
|
||||
|
||||
|
||||
install: all
|
||||
$(INSTALL_PROGRAM) $(SOBJS) $(DESTDIR) $(YAPLIBDIR)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ $(OBJS) $(SOBJS) *.BAK biftest xmlParser/*.o
|
||||
|
||||
|
||||
depend: $(HEADERS) $(CPP_SOURCES)
|
||||
-@if test "$(GCC)" = yes; then\
|
||||
$(CC) -MM -MG $(CFLAGS) -I$(srcdir) -I$(srcdir)/../../../../include -I$(srcdir)/../../../../H $(CPP_SOURCES) >> Makefile;\
|
||||
else\
|
||||
makedepend -f - -- $(CFLAGS) -I$(srcdir)/../../../../H -I$(srcdir)/../../../../include -- $(CPP_SOURCES) |\
|
||||
sed 's|.*/\([^:]*\):|\1:|' >> Makefile ;\
|
||||
fi
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
115
packages/CLPBN/clpbn/bp/Makefile.in
Normal file
115
packages/CLPBN/clpbn/bp/Makefile.in
Normal file
@ -0,0 +1,115 @@
|
||||
#
|
||||
# default base directory for YAP installation
|
||||
# (EROOT for architecture-dependent files)
|
||||
#
|
||||
GCC = @GCC@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
ROOTDIR = $(prefix)
|
||||
EROOTDIR = @exec_prefix@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
#
|
||||
# where the binary should be
|
||||
#
|
||||
BINDIR = $(EROOTDIR)/bin
|
||||
#
|
||||
# where YAP should look for libraries
|
||||
#
|
||||
LIBDIR=@libdir@
|
||||
YAPLIBDIR=@libdir@/Yap
|
||||
#
|
||||
#
|
||||
CC=@CC@
|
||||
CXX=@CXX@
|
||||
CXXFLAGS= @SHLIB_CXXFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../../.. -I$(srcdir)/../../../../include @CPPFLAGS@
|
||||
#
|
||||
#
|
||||
# You shouldn't need to change what follows.
|
||||
#
|
||||
INSTALL=@INSTALL@
|
||||
INSTALL_DATA=@INSTALL_DATA@
|
||||
INSTALL_PROGRAM=@INSTALL_PROGRAM@
|
||||
SHELL=/bin/sh
|
||||
RANLIB=@RANLIB@
|
||||
srcdir=@srcdir@
|
||||
SO=@SO@
|
||||
#4.1VPATH=@srcdir@:@srcdir@/OPTYap
|
||||
CWD=$(PWD)
|
||||
|
||||
|
||||
HEADERS = \
|
||||
$(srcdir)/BayesianNetwork.h \
|
||||
$(srcdir)/BayesianNode.h \
|
||||
$(srcdir)/BpNetwork.h \
|
||||
$(srcdir)/BpNode.h \
|
||||
$(srcdir)/Distribution.h \
|
||||
$(srcdir)/CptEntry.h \
|
||||
$(srcdir)/BifInterface.h \
|
||||
$(srcdir)/xmlParser/xmlParser.h
|
||||
|
||||
CPP_SOURCES = \
|
||||
$(srcdir)/BayesianNetwork.cpp \
|
||||
$(srcdir)/BayesianNode.cpp \
|
||||
$(srcdir)/BpNetwork.cpp \
|
||||
$(srcdir)/BpNode.cpp \
|
||||
$(srcdir)/Distribution.cpp \
|
||||
$(srcdir)/CptEntry.cpp \
|
||||
$(srcdir)/Horus.cpp \
|
||||
$(srcdir)/BifInterface.cpp \
|
||||
$(srcdir)/BifTest.cpp \
|
||||
$(srcdir)/xmlParser/xmlParser.cpp
|
||||
|
||||
OBJS = \
|
||||
BayesianNetwork.o \
|
||||
BayesianNode.o \
|
||||
BpNetwork.o \
|
||||
BpNode.o \
|
||||
Distribution.o \
|
||||
CptEntry.o \
|
||||
Horus.o
|
||||
|
||||
BIF_OBJS = \
|
||||
BayesianNetwork.o \
|
||||
BayesianNode.o \
|
||||
BpNetwork.o \
|
||||
BpNode.o \
|
||||
Distribution.o \
|
||||
CptEntry.o \
|
||||
BifInterface.o \
|
||||
BifTest.o \
|
||||
xmlParser/xmlParser.o
|
||||
|
||||
SOBJS=horus.@SO@
|
||||
|
||||
|
||||
all: $(SOBJS) biftest
|
||||
|
||||
# default rule
|
||||
%.o : $(srcdir)/%.cpp
|
||||
$(CXX) -c $(CXXFLAGS) $< -o $@
|
||||
|
||||
@DO_SECOND_LD@horus.@SO@: $(OBJS)
|
||||
@DO_SECOND_LD@ @SHLIB_CXX_LD@ -o horus.@SO@ $(OBJS)
|
||||
|
||||
biftest: $(BIF_OBJS)
|
||||
$(CXX) -o biftest $(BIF_OBJS)
|
||||
|
||||
|
||||
install: all
|
||||
$(INSTALL_PROGRAM) $(SOBJS) $(DESTDIR) $(YAPLIBDIR)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ $(OBJS) $(SOBJS) *.BAK biftest xmlParser/*.o
|
||||
|
||||
|
||||
depend: $(HEADERS) $(CPP_SOURCES)
|
||||
-@if test "$(GCC)" = yes; then\
|
||||
$(CC) -MM -MG $(CFLAGS) -I$(srcdir) -I$(srcdir)/../../../../include -I$(srcdir)/../../../../H $(CPP_SOURCES) >> Makefile;\
|
||||
else\
|
||||
makedepend -f - -- $(CFLAGS) -I$(srcdir)/../../../../H -I$(srcdir)/../../../../include -- $(CPP_SOURCES) |\
|
||||
sed 's|.*/\([^:]*\):|\1:|' >> Makefile ;\
|
||||
fi
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
BIN
packages/CLPBN/clpbn/bp/biftest
Executable file
BIN
packages/CLPBN/clpbn/bp/biftest
Executable file
Binary file not shown.
102
packages/CLPBN/clpbn/bp/bnets/dog-net.xml
Normal file
102
packages/CLPBN/clpbn/bp/bnets/dog-net.xml
Normal file
@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
|
||||
<!--
|
||||
Bayesian network in XMLBIF v0.3 (BayesNet Interchange Format)
|
||||
Produced by JavaBayes (http://www.cs.cmu.edu/~javabayes/
|
||||
Output created Wed Aug 12 21:16:40 GMT+01:00 1998
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<!-- DTD for the XMLBIF 0.3 format -->
|
||||
<!DOCTYPE BIF [
|
||||
<!ELEMENT BIF ( NETWORK )*>
|
||||
<!ATTLIST BIF VERSION CDATA #REQUIRED>
|
||||
<!ELEMENT NETWORK ( NAME, ( PROPERTY | VARIABLE | DEFINITION )* )>
|
||||
<!ELEMENT NAME (#PCDATA)>
|
||||
<!ELEMENT VARIABLE ( NAME, ( OUTCOME | PROPERTY )* ) >
|
||||
<!ATTLIST VARIABLE TYPE (nature|decision|utility) "nature">
|
||||
<!ELEMENT OUTCOME (#PCDATA)>
|
||||
<!ELEMENT DEFINITION ( FOR | GIVEN | TABLE | PROPERTY )* >
|
||||
<!ELEMENT FOR (#PCDATA)>
|
||||
<!ELEMENT GIVEN (#PCDATA)>
|
||||
<!ELEMENT TABLE (#PCDATA)>
|
||||
<!ELEMENT PROPERTY (#PCDATA)>
|
||||
]>
|
||||
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Dog-Problem</NAME>
|
||||
|
||||
<!-- Variables -->
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>light-on</NAME>
|
||||
<OUTCOME>true</OUTCOME>
|
||||
<OUTCOME>false</OUTCOME>
|
||||
<PROPERTY>position = (73, 165)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>bowel-problem</NAME>
|
||||
<OUTCOME>true</OUTCOME>
|
||||
<OUTCOME>false</OUTCOME>
|
||||
<PROPERTY>position = (190, 69)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>dog-out</NAME>
|
||||
<OUTCOME>true</OUTCOME>
|
||||
<OUTCOME>false</OUTCOME>
|
||||
<PROPERTY>position = (155, 165)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>hear-bark</NAME>
|
||||
<OUTCOME>true</OUTCOME>
|
||||
<OUTCOME>false</OUTCOME>
|
||||
<PROPERTY>position = (154, 241)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>family-out</NAME>
|
||||
<OUTCOME>true</OUTCOME>
|
||||
<OUTCOME>false</OUTCOME>
|
||||
<PROPERTY>position = (112, 69)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
|
||||
<!-- Probability distributions -->
|
||||
<DEFINITION>
|
||||
<FOR>light-on</FOR>
|
||||
<GIVEN>family-out</GIVEN>
|
||||
<TABLE>0.6 0.4 0.05 0.95 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>bowel-problem</FOR>
|
||||
<TABLE>0.01 0.99 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>dog-out</FOR>
|
||||
<GIVEN>bowel-problem</GIVEN>
|
||||
<GIVEN>family-out</GIVEN>
|
||||
<TABLE>0.99 0.01 0.97 0.03 0.9 0.1 0.3 0.7 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>hear-bark</FOR>
|
||||
<GIVEN>dog-out</GIVEN>
|
||||
<TABLE>0.7 0.3 0.01 0.99 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>family-out</FOR>
|
||||
<TABLE>0.15 0.85 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
106
packages/CLPBN/clpbn/bp/bnets/john-mary-call.xml
Normal file
106
packages/CLPBN/clpbn/bp/bnets/john-mary-call.xml
Normal file
@ -0,0 +1,106 @@
|
||||
<?XML VERSION="1.0"?>
|
||||
|
||||
|
||||
<!--
|
||||
Bayesian network in BIF (BayesNet Interchange Format)
|
||||
Produced by JavaBayes (http://www.cs.cmu.edu/~javabayes/
|
||||
Output created Fri Nov 14 13:14:15 GMT+00:00 1997
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<!-- DTD for the BIF format -->
|
||||
<!DOCTYPE BIF [
|
||||
<!ELEMENT PROPERTY (#PCDATA)>
|
||||
<!ELEMENT TYPE (#PCDATA)>
|
||||
<!ELEMENT VALUE (#PCDATA)>
|
||||
<!ELEMENT NAME (#PCDATA)>
|
||||
<!ELEMENT NETWORK
|
||||
( NAME, ( PROPERTY | VARIABLE | PROBABILITY )* )>
|
||||
<!ELEMENT VARIABLE ( NAME, TYPE, ( VALUE | PROPERTY )* ) >
|
||||
<!ELEMENT PROBABILITY
|
||||
( FOR | GIVEN | TABLE | ENTRY | DEFAULT | PROPERTY )* >
|
||||
<!ELEMENT TABLE (#PCDATA)>
|
||||
<!ELEMENT DEFAULT (TABLE)>
|
||||
<!ELEMENT ENTRY ( VALUE* , TABLE )>
|
||||
]>
|
||||
|
||||
|
||||
<BIF>
|
||||
<NETWORK>
|
||||
<NAME>John-Mary-Call</NAME>
|
||||
|
||||
<!-- Variables -->
|
||||
<VARIABLE>
|
||||
<NAME>Burglary</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (145, 114)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE>
|
||||
<NAME>Earthquake</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (351, 110)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE>
|
||||
<NAME>Alarm</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (253, 224)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE>
|
||||
<NAME>JohnCalls</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (156, 343)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE>
|
||||
<NAME>MaryCalls</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (344, 341)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
|
||||
<!-- Probability distributions -->
|
||||
<PROBABILITY>
|
||||
<FOR>Burglary</FOR>
|
||||
<TABLE>0.999 0.0010 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
<PROBABILITY>
|
||||
<FOR>Earthquake</FOR>
|
||||
<TABLE>0.998 0.0020 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
<PROBABILITY>
|
||||
<FOR>Alarm</FOR>
|
||||
<GIVEN>Burglary</GIVEN>
|
||||
<GIVEN>Earthquake</GIVEN>
|
||||
<TABLE>0.999 0.71 0.06 0.05 0.0010 0.29 0.94 0.95 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
<PROBABILITY>
|
||||
<FOR>JohnCalls</FOR>
|
||||
<GIVEN>Alarm</GIVEN>
|
||||
<TABLE>0.95 0.1 0.05 0.9 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
<PROBABILITY>
|
||||
<FOR>MaryCalls</FOR>
|
||||
<GIVEN>Alarm</GIVEN>
|
||||
<TABLE>0.99 0.3 0.01 0.7 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
|
||||
</BIF>
|
116
packages/CLPBN/clpbn/bp/bnets/more-than-2-parents-and-childs.xml
Normal file
116
packages/CLPBN/clpbn/bp/bnets/more-than-2-parents-and-childs.xml
Normal file
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Test</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
<OUTCOME>b3</OUTCOME>
|
||||
<OUTCOME>b4</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
<OUTCOME>c3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>D</NAME>
|
||||
<OUTCOME>d1</OUTCOME>
|
||||
<OUTCOME>d2</OUTCOME>
|
||||
<OUTCOME>d3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>E</NAME>
|
||||
<OUTCOME>e1</OUTCOME>
|
||||
<OUTCOME>e2</OUTCOME>
|
||||
<OUTCOME>e3</OUTCOME>
|
||||
<OUTCOME>e4</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>F</NAME>
|
||||
<OUTCOME>f1</OUTCOME>
|
||||
<OUTCOME>f2</OUTCOME>
|
||||
<OUTCOME>f3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>G</NAME>
|
||||
<OUTCOME>g1</OUTCOME>
|
||||
<OUTCOME>g2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE> .1 .2 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<TABLE> .01 .02 .03 .04 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<TABLE> .11 .22 .33 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>D</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<GIVEN>B</GIVEN>
|
||||
<GIVEN>C</GIVEN>
|
||||
<TABLE>
|
||||
.522 .008 .99 .01 .2 .8 .003 .457 .423 .007 .92 .04 .5 .232 .033 .227 .112 .048 .91 .21 .24 .18 .005 .227
|
||||
.212 .04 .59 .21 .6 .1 .023 .215 .913 .017 .96 .01 .55 .422 .013 .417 .272 .068 .61 .11 .26 .28 .205 .322
|
||||
.142 .028 .19 .11 .5 .67 .013 .437 .163 .067 .12 .06 .1 .262 .063 .167 .512 .028 .11 .41 .14 .68 .015 .92
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>E</FOR>
|
||||
<GIVEN>D</GIVEN>
|
||||
<TABLE>
|
||||
.111 .11 .1
|
||||
.222 .22 .2
|
||||
.333 .33 .3
|
||||
.444 .44 .4
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>F</FOR>
|
||||
<GIVEN>D</GIVEN>
|
||||
<TABLE>
|
||||
.112 .111 .110
|
||||
.223 .222 .221
|
||||
.334 .333 .332
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>G</FOR>
|
||||
<GIVEN>D</GIVEN>
|
||||
<TABLE>
|
||||
.101 .102 .103
|
||||
.201 .202 .203
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
84
packages/CLPBN/clpbn/bp/bnets/multiconnected.xml
Normal file
84
packages/CLPBN/clpbn/bp/bnets/multiconnected.xml
Normal file
@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
H
|
||||
/ \
|
||||
/ \
|
||||
B L
|
||||
\ / \
|
||||
\ / \
|
||||
F C
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Multiconnected</NAME>
|
||||
|
||||
<!-- Variables -->
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>H</NAME>
|
||||
<OUTCOME>h1</OUTCOME>
|
||||
<OUTCOME>h2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>L</NAME>
|
||||
<OUTCOME>l1</OUTCOME>
|
||||
<OUTCOME>l2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>F</NAME>
|
||||
<OUTCOME>f1</OUTCOME>
|
||||
<OUTCOME>f2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>H</FOR>
|
||||
<TABLE> .2 .8 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<GIVEN>H</GIVEN>
|
||||
<TABLE> .25 .75 .05 .95 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>L</FOR>
|
||||
<GIVEN>H</GIVEN>
|
||||
<TABLE> .003 .997 .00005 .99995 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>F</FOR>
|
||||
<GIVEN>B</GIVEN>
|
||||
<GIVEN>L</GIVEN>
|
||||
<TABLE> .75 .25 .1 .9 .5 .5 .05 .95 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<GIVEN>L</GIVEN>
|
||||
<TABLE> .6 .4 .02 .98 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
59
packages/CLPBN/clpbn/bp/bnets/multiconnected.yap
Normal file
59
packages/CLPBN/clpbn/bp/bnets/multiconnected.yap
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
:- use_module(library(clpbn)).
|
||||
|
||||
:- set_clpbn_flag(solver, bp).
|
||||
|
||||
|
||||
% H
|
||||
% / \
|
||||
% / \
|
||||
% B L
|
||||
% \ / \
|
||||
% \ / \
|
||||
% F C
|
||||
|
||||
|
||||
h(H) :-
|
||||
h_table(HDist),
|
||||
{ H = h with p([h1, h2], HDist) }.
|
||||
|
||||
|
||||
b(B) :-
|
||||
h(H),
|
||||
b_table(BDist),
|
||||
{ B = b with p([b1, b2], BDist, [H]) }.
|
||||
|
||||
|
||||
l(L) :-
|
||||
h(H),
|
||||
l_table(LDist),
|
||||
{ L = l with p([l1, l2], LDist, [H]) }.
|
||||
|
||||
|
||||
f(F) :-
|
||||
b(B),
|
||||
l(L),
|
||||
f_table(FDist),
|
||||
{ F = f with p([f1, f2], FDist, [B, L]) }.
|
||||
|
||||
|
||||
c(C) :-
|
||||
l(L),
|
||||
c_table(CDist),
|
||||
{ C = c with p([c1, c2], CDist, [L]) }.
|
||||
|
||||
|
||||
h_table([0.2, 0.8]).
|
||||
|
||||
b_table([0.25, 0.05,
|
||||
0.75, 0.95]).
|
||||
|
||||
l_table([0.003, 0.00005,
|
||||
0.997, 0.99995]).
|
||||
|
||||
f_table([0.75, 0.1, 0.5, 0.05,
|
||||
0.25, 0.9, 0.5, 0.95]).
|
||||
|
||||
c_table([0.6, 0.02,
|
||||
0.4, 0.98]).
|
||||
|
52
packages/CLPBN/clpbn/bp/bnets/neapolitan.xml
Normal file
52
packages/CLPBN/clpbn/bp/bnets/neapolitan.xml
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
|
||||
<!--
|
||||
Bayesian network in XMLBIF v0.3 (BayesNet Interchange Format)
|
||||
Produced by JavaBayes (http://www.cs.cmu.edu/~javabayes/
|
||||
Output created Wed Aug 12 21:16:40 GMT+01:00 1998
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Neapolitan</NAME>
|
||||
|
||||
<!-- Variables -->
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>Burglar</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>FreightTruck</NAME>
|
||||
<OUTCOME>f1</OUTCOME>
|
||||
<OUTCOME>f2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>Alarm</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>Burglar</FOR>
|
||||
<TABLE> .005 .995 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>FreightTruck</FOR>
|
||||
<TABLE> .03 .97 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>Alarm</FOR>
|
||||
<GIVEN>Burglar</GIVEN>
|
||||
<GIVEN>FreightTruck</GIVEN>
|
||||
<TABLE> .992 .008 .99 .01 .2 .8 .003 .997 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
35
packages/CLPBN/clpbn/bp/bnets/neapolitan.yap
Normal file
35
packages/CLPBN/clpbn/bp/bnets/neapolitan.yap
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
:- use_module(library(clpbn)).
|
||||
|
||||
:- set_clpbn_flag(solver, bp).
|
||||
|
||||
|
||||
% B F
|
||||
% \ /
|
||||
% \ /
|
||||
% A
|
||||
|
||||
|
||||
a(A) :-
|
||||
b(B),
|
||||
f(F),
|
||||
a_table(ADist),
|
||||
{ A = a with p([a1, a2], ADist, [B, F]) }.
|
||||
|
||||
|
||||
|
||||
b(B) :-
|
||||
b_table(BDist),
|
||||
{ B = b with p([b1, b2], BDist) }.
|
||||
|
||||
f(F) :-
|
||||
f_table(FDist),
|
||||
{ F = f with p([f1, f2], FDist) }.
|
||||
|
||||
b_table([0.005, 0.995]).
|
||||
|
||||
f_table([0.03, 0.97]).
|
||||
|
||||
a_table([0.992, 0.99, 0.2, 0.003,
|
||||
0.008, 0.01, 0.8, 0.997]).
|
||||
|
57
packages/CLPBN/clpbn/bp/bnets/simple-loop.xml
Normal file
57
packages/CLPBN/clpbn/bp/bnets/simple-loop.xml
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Simple Loop</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>D</NAME>
|
||||
<OUTCOME>d1</OUTCOME>
|
||||
<OUTCOME>d2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE> .01 .09 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<TABLE> .03 .97 .6 .4</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<TABLE> .24 .76 .12 .88</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>D</FOR>
|
||||
<GIVEN>B</GIVEN>
|
||||
<GIVEN>C</GIVEN>
|
||||
<TABLE> .2 .8 .7 .3 .45 .55 .22 .78 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
36
packages/CLPBN/clpbn/bp/bnets/test.yap
Normal file
36
packages/CLPBN/clpbn/bp/bnets/test.yap
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
:- use_module(library(clpbn)).
|
||||
|
||||
:- set_clpbn_flag(solver, bp).
|
||||
|
||||
|
||||
% B F
|
||||
% \ /
|
||||
% \ /
|
||||
% A
|
||||
|
||||
|
||||
a(A) :-
|
||||
b(B),
|
||||
f(F),
|
||||
a_table(ADist),
|
||||
{ A = a with p([a1, a2, a3], ADist, [B, F]) }.
|
||||
|
||||
|
||||
|
||||
b(B) :-
|
||||
b_table(BDist),
|
||||
{ B = b with p([b1, b2], BDist) }.
|
||||
|
||||
f(F) :-
|
||||
f_table(FDist),
|
||||
{ F = f with p([f1, f2], FDist) }.
|
||||
|
||||
b_table([0.005, 0.995]).
|
||||
|
||||
f_table([0.03, 0.97]).
|
||||
|
||||
a_table([0.992, 0.99, 0.2, 0.003,
|
||||
0.008, 0.01, 0.8, 0.997,
|
||||
0.018, 0.21, 0.2, 0.927]).
|
||||
|
21187
packages/CLPBN/clpbn/bp/out.damping.txt
Normal file
21187
packages/CLPBN/clpbn/bp/out.damping.txt
Normal file
File diff suppressed because it is too large
Load Diff
762
packages/CLPBN/clpbn/bp/out.txt
Normal file
762
packages/CLPBN/clpbn/bp/out.txt
Normal file
@ -0,0 +1,762 @@
|
||||
Variable: Burglar
|
||||
Domain: b1, b2
|
||||
Parents:
|
||||
Childs: Alarm
|
||||
cpt
|
||||
----------------
|
||||
b1 0.005
|
||||
b2 0.995
|
||||
|
||||
Variable: FreightTruck
|
||||
Domain: f1, f2
|
||||
Parents:
|
||||
Childs: Alarm
|
||||
cpt
|
||||
----------------
|
||||
f1 0.03
|
||||
f2 0.97
|
||||
|
||||
Variable: Alarm
|
||||
Domain: a1, a2
|
||||
Parents: Burglar, FreightTruck
|
||||
Childs:
|
||||
cpt b1,f1 b1,f2 b2,f1 b2,f2
|
||||
----------------------------------------------------
|
||||
a1 0.992 0.99 0.2 0.003
|
||||
a2 0.008 0.01 0.8 0.997
|
||||
|
||||
Variable: Burglar
|
||||
Domain: b1, b2
|
||||
Parents:
|
||||
Childs: Alarm
|
||||
cpt
|
||||
----------------
|
||||
b1 0.005
|
||||
b2 0.995
|
||||
|
||||
Variable: FreightTruck
|
||||
Domain: f1, f2
|
||||
Parents:
|
||||
Childs: Alarm, _Jn
|
||||
cpt
|
||||
----------------
|
||||
f1 0.03
|
||||
f2 0.97
|
||||
|
||||
Variable: Alarm
|
||||
Domain: a1, a2
|
||||
Parents: Burglar, FreightTruck
|
||||
Childs: _Jn
|
||||
cpt b1,f1 b1,f2 b2,f1 b2,f2
|
||||
----------------------------------------------------
|
||||
a1 0.992 0.99 0.2 0.003
|
||||
a2 0.008 0.01 0.8 0.997
|
||||
|
||||
Variable: _Jn
|
||||
Domain: _jn0, _jn1, _jn2, _jn3
|
||||
Parents: FreightTruck, Alarm
|
||||
Childs:
|
||||
cpt f1,a1 f1,a2 f2,a1 f2,a2
|
||||
----------------------------------------------------
|
||||
_jn0 1 0 0 0
|
||||
_jn1 0 1 0 0
|
||||
_jn2 0 0 1 0
|
||||
_jn3 0 0 0 1
|
||||
|
||||
The graph is not single connected. Iterative belief propagation will be used.
|
||||
|
||||
Initializing solver
|
||||
-> schedule = parallel
|
||||
-> max iters = 100
|
||||
-> stable threashold = 1e-20
|
||||
-> query vars = FreightTruck Alarm
|
||||
domain π(Burglar) λ(Burglar) belief
|
||||
----------------------------------------------------------------
|
||||
b1 1 1 0.5
|
||||
b2 1 1 0.5
|
||||
|
||||
domain πAlarm(Burglar) λAlarm(Burglar)
|
||||
----------------------------------------------------------------
|
||||
b1 0.5 0.5
|
||||
b2 0.5 0.5
|
||||
|
||||
domain π(FreightTruck) λ(FreightTruck) belief
|
||||
----------------------------------------------------------------
|
||||
f1 1 1 0.5
|
||||
f2 1 1 0.5
|
||||
|
||||
domain πAlarm(FreightTruck) λAlarm(FreightTruck)
|
||||
----------------------------------------------------------------
|
||||
f1 0.5 0.5
|
||||
f2 0.5 0.5
|
||||
|
||||
domain π_Jn(FreightTruck) λ_Jn(FreightTruck)
|
||||
----------------------------------------------------------------
|
||||
f1 0.5 0.5
|
||||
f2 0.5 0.5
|
||||
|
||||
domain π(Alarm) λ(Alarm) belief
|
||||
----------------------------------------------------------------
|
||||
a1 1 1 0.5
|
||||
a2 1 1 0.5
|
||||
|
||||
domain π_Jn(Alarm) λ_Jn(Alarm)
|
||||
----------------------------------------------------------------
|
||||
a1 0.5 0.5
|
||||
a2 0.5 0.5
|
||||
|
||||
domain π(_Jn) λ(_Jn) belief
|
||||
----------------------------------------------------------------
|
||||
_jn0 1 1 0.25
|
||||
_jn1 1 1 0.25
|
||||
_jn2 1 1 0.25
|
||||
_jn3 1 1 0.25
|
||||
|
||||
|
||||
|
||||
********************************************************************************
|
||||
Iteration 1
|
||||
********************************************************************************
|
||||
λ message Alarm --> Burglar
|
||||
λAlarm(b1)
|
||||
= [p(a1|b1,f1).πAlarm(f1) + p(a1|b1,f2).πAlarm(f2)].λ(a1)
|
||||
+ [p(a2|b1,f1).πAlarm(f1) + p(a2|b1,f2).πAlarm(f2)].λ(a2)
|
||||
= [(0.992x0.5) + (0.99x0.5)]x1
|
||||
+ [(0.008x0.5) + (0.01x0.5)]x1 = 1
|
||||
λAlarm(b2)
|
||||
= [p(a1|b2,f1).πAlarm(f1) + p(a1|b2,f2).πAlarm(f2)].λ(a1)
|
||||
+ [p(a2|b2,f1).πAlarm(f1) + p(a2|b2,f2).πAlarm(f2)].λ(a2)
|
||||
= [(0.2x0.5) + (0.003x0.5)]x1
|
||||
+ [(0.8x0.5) + (0.997x0.5)]x1 = 1
|
||||
|
||||
λ message Alarm --> FreightTruck
|
||||
λAlarm(f1)
|
||||
= [p(a1|b1,f1).πAlarm(b1) + p(a1|b2,f1).πAlarm(b2)].λ(a1)
|
||||
+ [p(a2|b1,f1).πAlarm(b1) + p(a2|b2,f1).πAlarm(b2)].λ(a2)
|
||||
= [(0.992x0.5) + (0.2x0.5)]x1
|
||||
+ [(0.008x0.5) + (0.8x0.5)]x1 = 1
|
||||
λAlarm(f2)
|
||||
= [p(a1|b1,f2).πAlarm(b1) + p(a1|b2,f2).πAlarm(b2)].λ(a1)
|
||||
+ [p(a2|b1,f2).πAlarm(b1) + p(a2|b2,f2).πAlarm(b2)].λ(a2)
|
||||
= [(0.99x0.5) + (0.003x0.5)]x1
|
||||
+ [(0.01x0.5) + (0.997x0.5)]x1 = 1
|
||||
|
||||
λ message _Jn --> FreightTruck
|
||||
λ_Jn(f1)
|
||||
= [p(_jn0|f1,a1).π_Jn(a1) + p(_jn0|f1,a2).π_Jn(a2)].λ(_jn0)
|
||||
+ [p(_jn1|f1,a1).π_Jn(a1) + p(_jn1|f1,a2).π_Jn(a2)].λ(_jn1)
|
||||
+ [p(_jn2|f1,a1).π_Jn(a1) + p(_jn2|f1,a2).π_Jn(a2)].λ(_jn2)
|
||||
+ [p(_jn3|f1,a1).π_Jn(a1) + p(_jn3|f1,a2).π_Jn(a2)].λ(_jn3)
|
||||
= [(1x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (1x0.5)]x1
|
||||
+ [(0x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (0x0.5)]x1 = 1
|
||||
λ_Jn(f2)
|
||||
= [p(_jn0|f2,a1).π_Jn(a1) + p(_jn0|f2,a2).π_Jn(a2)].λ(_jn0)
|
||||
+ [p(_jn1|f2,a1).π_Jn(a1) + p(_jn1|f2,a2).π_Jn(a2)].λ(_jn1)
|
||||
+ [p(_jn2|f2,a1).π_Jn(a1) + p(_jn2|f2,a2).π_Jn(a2)].λ(_jn2)
|
||||
+ [p(_jn3|f2,a1).π_Jn(a1) + p(_jn3|f2,a2).π_Jn(a2)].λ(_jn3)
|
||||
= [(0x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (0x0.5)]x1
|
||||
+ [(1x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (1x0.5)]x1 = 1
|
||||
|
||||
λ message _Jn --> Alarm
|
||||
λ_Jn(a1)
|
||||
= [p(_jn0|f1,a1).π_Jn(f1) + p(_jn0|f2,a1).π_Jn(f2)].λ(_jn0)
|
||||
+ [p(_jn1|f1,a1).π_Jn(f1) + p(_jn1|f2,a1).π_Jn(f2)].λ(_jn1)
|
||||
+ [p(_jn2|f1,a1).π_Jn(f1) + p(_jn2|f2,a1).π_Jn(f2)].λ(_jn2)
|
||||
+ [p(_jn3|f1,a1).π_Jn(f1) + p(_jn3|f2,a1).π_Jn(f2)].λ(_jn3)
|
||||
= [(1x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (1x0.5)]x1
|
||||
+ [(0x0.5) + (0x0.5)]x1 = 1
|
||||
λ_Jn(a2)
|
||||
= [p(_jn0|f1,a2).π_Jn(f1) + p(_jn0|f2,a2).π_Jn(f2)].λ(_jn0)
|
||||
+ [p(_jn1|f1,a2).π_Jn(f1) + p(_jn1|f2,a2).π_Jn(f2)].λ(_jn1)
|
||||
+ [p(_jn2|f1,a2).π_Jn(f1) + p(_jn2|f2,a2).π_Jn(f2)].λ(_jn2)
|
||||
+ [p(_jn3|f1,a2).π_Jn(f1) + p(_jn3|f2,a2).π_Jn(f2)].λ(_jn3)
|
||||
= [(0x0.5) + (0x0.5)]x1
|
||||
+ [(1x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (1x0.5)]x1 = 1
|
||||
|
||||
π message Burglar --> Alarm
|
||||
πAlarm(b1) = π(b1) = 0.005 = 0.005
|
||||
πAlarm(b2) = π(b2) = 0.995 = 0.995
|
||||
|
||||
π message FreightTruck --> Alarm
|
||||
πAlarm(f1) = π(f1).λ_Jn(f1) = 0.03 x 0.5 = 0.015
|
||||
πAlarm(f2) = π(f2).λ_Jn(f2) = 0.97 x 0.5 = 0.485
|
||||
|
||||
π message FreightTruck --> _Jn
|
||||
π_Jn(f1) = π(f1).λAlarm(f1) = 0.03 x 0.5 = 0.015
|
||||
π_Jn(f2) = π(f2).λAlarm(f2) = 0.97 x 0.5 = 0.485
|
||||
|
||||
π message Alarm --> _Jn
|
||||
π_Jn(a1) = π(a1) = 1 = 1
|
||||
π_Jn(a2) = π(a2) = 1 = 1
|
||||
|
||||
var Burglar:
|
||||
π(b1)
|
||||
= p(b1)
|
||||
= (0.005) = 0.005
|
||||
π(b2)
|
||||
= p(b2)
|
||||
= (0.995) = 0.995
|
||||
λ(b1) = λAlarm(b1) = 0.5 = 0.5
|
||||
λ(b2) = λAlarm(b2) = 0.5 = 0.5
|
||||
belief change = 1
|
||||
|
||||
var FreightTruck:
|
||||
π(f1)
|
||||
= p(f1)
|
||||
= (0.03) = 0.03
|
||||
π(f2)
|
||||
= p(f2)
|
||||
= (0.97) = 0.97
|
||||
λ(f1) = λAlarm(f1).λ_Jn(f1) = 0.5 x 0.5 = 0.25
|
||||
λ(f2) = λAlarm(f2).λ_Jn(f2) = 0.5 x 0.5 = 0.25
|
||||
belief change = 1
|
||||
|
||||
var Alarm:
|
||||
π(a1)
|
||||
= p(a1|b1,f1).πAlarm(b1).πAlarm(f1)
|
||||
+ p(a1|b1,f2).πAlarm(b1).πAlarm(f2)
|
||||
+ p(a1|b2,f1).πAlarm(b2).πAlarm(f1)
|
||||
+ p(a1|b2,f2).πAlarm(b2).πAlarm(f2)
|
||||
= (0.992x0.005x0.03)
|
||||
+ (0.99x0.005x0.97)
|
||||
+ (0.2x0.995x0.03)
|
||||
+ (0.003x0.995x0.97) = 0.01381575
|
||||
π(a2)
|
||||
= p(a2|b1,f1).πAlarm(b1).πAlarm(f1)
|
||||
+ p(a2|b1,f2).πAlarm(b1).πAlarm(f2)
|
||||
+ p(a2|b2,f1).πAlarm(b2).πAlarm(f1)
|
||||
+ p(a2|b2,f2).πAlarm(b2).πAlarm(f2)
|
||||
= (0.008x0.005x0.03)
|
||||
+ (0.01x0.005x0.97)
|
||||
+ (0.8x0.995x0.03)
|
||||
+ (0.997x0.995x0.97) = 0.98618425
|
||||
λ(a1) = λ_Jn(a1) = 0.5 = 0.5
|
||||
λ(a2) = λ_Jn(a2) = 0.5 = 0.5
|
||||
belief change = 1
|
||||
|
||||
var _Jn:
|
||||
π(_jn0)
|
||||
= p(_jn0|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn0|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn0|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn0|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (1x0.03x0.5)
|
||||
+ (0x0.03x0.5)
|
||||
+ (0x0.97x0.5)
|
||||
+ (0x0.97x0.5) = 0.015
|
||||
π(_jn1)
|
||||
= p(_jn1|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn1|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn1|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn1|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (0x0.03x0.5)
|
||||
+ (1x0.03x0.5)
|
||||
+ (0x0.97x0.5)
|
||||
+ (0x0.97x0.5) = 0.015
|
||||
π(_jn2)
|
||||
= p(_jn2|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn2|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn2|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn2|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (0x0.03x0.5)
|
||||
+ (0x0.03x0.5)
|
||||
+ (1x0.97x0.5)
|
||||
+ (0x0.97x0.5) = 0.485
|
||||
π(_jn3)
|
||||
= p(_jn3|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn3|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn3|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn3|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (0x0.03x0.5)
|
||||
+ (0x0.03x0.5)
|
||||
+ (0x0.97x0.5)
|
||||
+ (1x0.97x0.5) = 0.485
|
||||
λ(_jn0) = 1
|
||||
λ(_jn1) = 1
|
||||
λ(_jn2) = 1
|
||||
λ(_jn3) = 1
|
||||
belief change = 1
|
||||
|
||||
domain π(Burglar) λ(Burglar) belief
|
||||
----------------------------------------------------------------
|
||||
b1 0.005 0.5 0.005
|
||||
b2 0.995 0.5 0.995
|
||||
|
||||
domain πAlarm(Burglar) λAlarm(Burglar)
|
||||
----------------------------------------------------------------
|
||||
b1 0.005 0.5
|
||||
b2 0.995 0.5
|
||||
|
||||
domain π(FreightTruck) λ(FreightTruck) belief
|
||||
----------------------------------------------------------------
|
||||
f1 0.03 0.25 0.03
|
||||
f2 0.97 0.25 0.97
|
||||
|
||||
domain πAlarm(FreightTruck) λAlarm(FreightTruck)
|
||||
----------------------------------------------------------------
|
||||
f1 0.03 0.5
|
||||
f2 0.97 0.5
|
||||
|
||||
domain π_Jn(FreightTruck) λ_Jn(FreightTruck)
|
||||
----------------------------------------------------------------
|
||||
f1 0.03 0.5
|
||||
f2 0.97 0.5
|
||||
|
||||
domain π(Alarm) λ(Alarm) belief
|
||||
----------------------------------------------------------------
|
||||
a1 0.01381575 0.5 0.01381575
|
||||
a2 0.98618425 0.5 0.98618425
|
||||
|
||||
domain π_Jn(Alarm) λ_Jn(Alarm)
|
||||
----------------------------------------------------------------
|
||||
a1 0.5 0.5
|
||||
a2 0.5 0.5
|
||||
|
||||
domain π(_Jn) λ(_Jn) belief
|
||||
----------------------------------------------------------------
|
||||
_jn0 0.015 1 0.015
|
||||
_jn1 0.015 1 0.015
|
||||
_jn2 0.485 1 0.485
|
||||
_jn3 0.485 1 0.485
|
||||
|
||||
|
||||
|
||||
********************************************************************************
|
||||
Iteration 2
|
||||
********************************************************************************
|
||||
λ message Alarm --> Burglar
|
||||
λAlarm(b1)
|
||||
= [p(a1|b1,f1).πAlarm(f1) + p(a1|b1,f2).πAlarm(f2)].λ(a1)
|
||||
+ [p(a2|b1,f1).πAlarm(f1) + p(a2|b1,f2).πAlarm(f2)].λ(a2)
|
||||
= [(0.992x0.03) + (0.99x0.97)]x0.5
|
||||
+ [(0.008x0.03) + (0.01x0.97)]x0.5 = 0.5
|
||||
λAlarm(b2)
|
||||
= [p(a1|b2,f1).πAlarm(f1) + p(a1|b2,f2).πAlarm(f2)].λ(a1)
|
||||
+ [p(a2|b2,f1).πAlarm(f1) + p(a2|b2,f2).πAlarm(f2)].λ(a2)
|
||||
= [(0.2x0.03) + (0.003x0.97)]x0.5
|
||||
+ [(0.8x0.03) + (0.997x0.97)]x0.5 = 0.5
|
||||
|
||||
λ message Alarm --> FreightTruck
|
||||
λAlarm(f1)
|
||||
= [p(a1|b1,f1).πAlarm(b1) + p(a1|b2,f1).πAlarm(b2)].λ(a1)
|
||||
+ [p(a2|b1,f1).πAlarm(b1) + p(a2|b2,f1).πAlarm(b2)].λ(a2)
|
||||
= [(0.992x0.005) + (0.2x0.995)]x0.5
|
||||
+ [(0.008x0.005) + (0.8x0.995)]x0.5 = 0.5
|
||||
λAlarm(f2)
|
||||
= [p(a1|b1,f2).πAlarm(b1) + p(a1|b2,f2).πAlarm(b2)].λ(a1)
|
||||
+ [p(a2|b1,f2).πAlarm(b1) + p(a2|b2,f2).πAlarm(b2)].λ(a2)
|
||||
= [(0.99x0.005) + (0.003x0.995)]x0.5
|
||||
+ [(0.01x0.005) + (0.997x0.995)]x0.5 = 0.5
|
||||
|
||||
λ message _Jn --> FreightTruck
|
||||
λ_Jn(f1)
|
||||
= [p(_jn0|f1,a1).π_Jn(a1) + p(_jn0|f1,a2).π_Jn(a2)].λ(_jn0)
|
||||
+ [p(_jn1|f1,a1).π_Jn(a1) + p(_jn1|f1,a2).π_Jn(a2)].λ(_jn1)
|
||||
+ [p(_jn2|f1,a1).π_Jn(a1) + p(_jn2|f1,a2).π_Jn(a2)].λ(_jn2)
|
||||
+ [p(_jn3|f1,a1).π_Jn(a1) + p(_jn3|f1,a2).π_Jn(a2)].λ(_jn3)
|
||||
= [(1x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (1x0.5)]x1
|
||||
+ [(0x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (0x0.5)]x1 = 1
|
||||
λ_Jn(f2)
|
||||
= [p(_jn0|f2,a1).π_Jn(a1) + p(_jn0|f2,a2).π_Jn(a2)].λ(_jn0)
|
||||
+ [p(_jn1|f2,a1).π_Jn(a1) + p(_jn1|f2,a2).π_Jn(a2)].λ(_jn1)
|
||||
+ [p(_jn2|f2,a1).π_Jn(a1) + p(_jn2|f2,a2).π_Jn(a2)].λ(_jn2)
|
||||
+ [p(_jn3|f2,a1).π_Jn(a1) + p(_jn3|f2,a2).π_Jn(a2)].λ(_jn3)
|
||||
= [(0x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (0x0.5)]x1
|
||||
+ [(1x0.5) + (0x0.5)]x1
|
||||
+ [(0x0.5) + (1x0.5)]x1 = 1
|
||||
|
||||
λ message _Jn --> Alarm
|
||||
λ_Jn(a1)
|
||||
= [p(_jn0|f1,a1).π_Jn(f1) + p(_jn0|f2,a1).π_Jn(f2)].λ(_jn0)
|
||||
+ [p(_jn1|f1,a1).π_Jn(f1) + p(_jn1|f2,a1).π_Jn(f2)].λ(_jn1)
|
||||
+ [p(_jn2|f1,a1).π_Jn(f1) + p(_jn2|f2,a1).π_Jn(f2)].λ(_jn2)
|
||||
+ [p(_jn3|f1,a1).π_Jn(f1) + p(_jn3|f2,a1).π_Jn(f2)].λ(_jn3)
|
||||
= [(1x0.03) + (0x0.97)]x1
|
||||
+ [(0x0.03) + (0x0.97)]x1
|
||||
+ [(0x0.03) + (1x0.97)]x1
|
||||
+ [(0x0.03) + (0x0.97)]x1 = 1
|
||||
λ_Jn(a2)
|
||||
= [p(_jn0|f1,a2).π_Jn(f1) + p(_jn0|f2,a2).π_Jn(f2)].λ(_jn0)
|
||||
+ [p(_jn1|f1,a2).π_Jn(f1) + p(_jn1|f2,a2).π_Jn(f2)].λ(_jn1)
|
||||
+ [p(_jn2|f1,a2).π_Jn(f1) + p(_jn2|f2,a2).π_Jn(f2)].λ(_jn2)
|
||||
+ [p(_jn3|f1,a2).π_Jn(f1) + p(_jn3|f2,a2).π_Jn(f2)].λ(_jn3)
|
||||
= [(0x0.03) + (0x0.97)]x1
|
||||
+ [(1x0.03) + (0x0.97)]x1
|
||||
+ [(0x0.03) + (0x0.97)]x1
|
||||
+ [(0x0.03) + (1x0.97)]x1 = 1
|
||||
|
||||
π message Burglar --> Alarm
|
||||
πAlarm(b1) = π(b1) = 0.005 = 0.005
|
||||
πAlarm(b2) = π(b2) = 0.995 = 0.995
|
||||
|
||||
π message FreightTruck --> Alarm
|
||||
πAlarm(f1) = π(f1).λ_Jn(f1) = 0.03 x 0.5 = 0.015
|
||||
πAlarm(f2) = π(f2).λ_Jn(f2) = 0.97 x 0.5 = 0.485
|
||||
|
||||
π message FreightTruck --> _Jn
|
||||
π_Jn(f1) = π(f1).λAlarm(f1) = 0.03 x 0.5 = 0.015
|
||||
π_Jn(f2) = π(f2).λAlarm(f2) = 0.97 x 0.5 = 0.485
|
||||
|
||||
π message Alarm --> _Jn
|
||||
π_Jn(a1) = π(a1) = 0.0138158 = 0.01381575
|
||||
π_Jn(a2) = π(a2) = 0.986184 = 0.98618425
|
||||
|
||||
var Burglar:
|
||||
π(b1)
|
||||
= p(b1)
|
||||
= (0.005) = 0.005
|
||||
π(b2)
|
||||
= p(b2)
|
||||
= (0.995) = 0.995
|
||||
λ(b1) = λAlarm(b1) = 0.5 = 0.5
|
||||
λ(b2) = λAlarm(b2) = 0.5 = 0.5
|
||||
belief change = 8.67361738e-19
|
||||
|
||||
var FreightTruck:
|
||||
π(f1)
|
||||
= p(f1)
|
||||
= (0.03) = 0.03
|
||||
π(f2)
|
||||
= p(f2)
|
||||
= (0.97) = 0.97
|
||||
λ(f1) = λAlarm(f1).λ_Jn(f1) = 0.5 x 0.5 = 0.25
|
||||
λ(f2) = λAlarm(f2).λ_Jn(f2) = 0.5 x 0.5 = 0.25
|
||||
belief change = 0
|
||||
|
||||
var Alarm:
|
||||
π(a1)
|
||||
= p(a1|b1,f1).πAlarm(b1).πAlarm(f1)
|
||||
+ p(a1|b1,f2).πAlarm(b1).πAlarm(f2)
|
||||
+ p(a1|b2,f1).πAlarm(b2).πAlarm(f1)
|
||||
+ p(a1|b2,f2).πAlarm(b2).πAlarm(f2)
|
||||
= (0.992x0.005x0.03)
|
||||
+ (0.99x0.005x0.97)
|
||||
+ (0.2x0.995x0.03)
|
||||
+ (0.003x0.995x0.97) = 0.01381575
|
||||
π(a2)
|
||||
= p(a2|b1,f1).πAlarm(b1).πAlarm(f1)
|
||||
+ p(a2|b1,f2).πAlarm(b1).πAlarm(f2)
|
||||
+ p(a2|b2,f1).πAlarm(b2).πAlarm(f1)
|
||||
+ p(a2|b2,f2).πAlarm(b2).πAlarm(f2)
|
||||
= (0.008x0.005x0.03)
|
||||
+ (0.01x0.005x0.97)
|
||||
+ (0.8x0.995x0.03)
|
||||
+ (0.997x0.995x0.97) = 0.98618425
|
||||
λ(a1) = λ_Jn(a1) = 0.5 = 0.5
|
||||
λ(a2) = λ_Jn(a2) = 0.5 = 0.5
|
||||
belief change = 0
|
||||
|
||||
var _Jn:
|
||||
π(_jn0)
|
||||
= p(_jn0|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn0|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn0|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn0|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (1x0.03x0.0138158)
|
||||
+ (0x0.03x0.986184)
|
||||
+ (0x0.97x0.0138158)
|
||||
+ (0x0.97x0.986184) = 0.0004144725
|
||||
π(_jn1)
|
||||
= p(_jn1|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn1|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn1|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn1|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (0x0.03x0.0138158)
|
||||
+ (1x0.03x0.986184)
|
||||
+ (0x0.97x0.0138158)
|
||||
+ (0x0.97x0.986184) = 0.0295855275
|
||||
π(_jn2)
|
||||
= p(_jn2|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn2|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn2|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn2|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (0x0.03x0.0138158)
|
||||
+ (0x0.03x0.986184)
|
||||
+ (1x0.97x0.0138158)
|
||||
+ (0x0.97x0.986184) = 0.0134012775
|
||||
π(_jn3)
|
||||
= p(_jn3|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn3|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn3|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn3|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (0x0.03x0.0138158)
|
||||
+ (0x0.03x0.986184)
|
||||
+ (0x0.97x0.0138158)
|
||||
+ (1x0.97x0.986184) = 0.9565987225
|
||||
λ(_jn0) = 1
|
||||
λ(_jn1) = 1
|
||||
λ(_jn2) = 1
|
||||
λ(_jn3) = 1
|
||||
belief change = 0.9723685
|
||||
|
||||
domain π(Burglar) λ(Burglar) belief
|
||||
----------------------------------------------------------------
|
||||
b1 0.005 0.5 0.005
|
||||
b2 0.995 0.5 0.995
|
||||
|
||||
domain πAlarm(Burglar) λAlarm(Burglar)
|
||||
----------------------------------------------------------------
|
||||
b1 0.005 0.5
|
||||
b2 0.995 0.5
|
||||
|
||||
domain π(FreightTruck) λ(FreightTruck) belief
|
||||
----------------------------------------------------------------
|
||||
f1 0.03 0.25 0.03
|
||||
f2 0.97 0.25 0.97
|
||||
|
||||
domain πAlarm(FreightTruck) λAlarm(FreightTruck)
|
||||
----------------------------------------------------------------
|
||||
f1 0.03 0.5
|
||||
f2 0.97 0.5
|
||||
|
||||
domain π_Jn(FreightTruck) λ_Jn(FreightTruck)
|
||||
----------------------------------------------------------------
|
||||
f1 0.03 0.5
|
||||
f2 0.97 0.5
|
||||
|
||||
domain π(Alarm) λ(Alarm) belief
|
||||
----------------------------------------------------------------
|
||||
a1 0.01381575 0.5 0.01381575
|
||||
a2 0.98618425 0.5 0.98618425
|
||||
|
||||
domain π_Jn(Alarm) λ_Jn(Alarm)
|
||||
----------------------------------------------------------------
|
||||
a1 0.01381575 0.5
|
||||
a2 0.98618425 0.5
|
||||
|
||||
domain π(_Jn) λ(_Jn) belief
|
||||
----------------------------------------------------------------
|
||||
_jn0 0.0004144725 1 0.0004144725
|
||||
_jn1 0.0295855275 1 0.0295855275
|
||||
_jn2 0.0134012775 1 0.0134012775
|
||||
_jn3 0.9565987225 1 0.9565987225
|
||||
|
||||
|
||||
|
||||
********************************************************************************
|
||||
Iteration 3
|
||||
********************************************************************************
|
||||
λ message Alarm --> Burglar
|
||||
λAlarm(b1)
|
||||
= [p(a1|b1,f1).πAlarm(f1) + p(a1|b1,f2).πAlarm(f2)].λ(a1)
|
||||
+ [p(a2|b1,f1).πAlarm(f1) + p(a2|b1,f2).πAlarm(f2)].λ(a2)
|
||||
= [(0.992x0.03) + (0.99x0.97)]x0.5
|
||||
+ [(0.008x0.03) + (0.01x0.97)]x0.5 = 0.5
|
||||
λAlarm(b2)
|
||||
= [p(a1|b2,f1).πAlarm(f1) + p(a1|b2,f2).πAlarm(f2)].λ(a1)
|
||||
+ [p(a2|b2,f1).πAlarm(f1) + p(a2|b2,f2).πAlarm(f2)].λ(a2)
|
||||
= [(0.2x0.03) + (0.003x0.97)]x0.5
|
||||
+ [(0.8x0.03) + (0.997x0.97)]x0.5 = 0.5
|
||||
|
||||
λ message Alarm --> FreightTruck
|
||||
λAlarm(f1)
|
||||
= [p(a1|b1,f1).πAlarm(b1) + p(a1|b2,f1).πAlarm(b2)].λ(a1)
|
||||
+ [p(a2|b1,f1).πAlarm(b1) + p(a2|b2,f1).πAlarm(b2)].λ(a2)
|
||||
= [(0.992x0.005) + (0.2x0.995)]x0.5
|
||||
+ [(0.008x0.005) + (0.8x0.995)]x0.5 = 0.5
|
||||
λAlarm(f2)
|
||||
= [p(a1|b1,f2).πAlarm(b1) + p(a1|b2,f2).πAlarm(b2)].λ(a1)
|
||||
+ [p(a2|b1,f2).πAlarm(b1) + p(a2|b2,f2).πAlarm(b2)].λ(a2)
|
||||
= [(0.99x0.005) + (0.003x0.995)]x0.5
|
||||
+ [(0.01x0.005) + (0.997x0.995)]x0.5 = 0.5
|
||||
|
||||
λ message _Jn --> FreightTruck
|
||||
λ_Jn(f1)
|
||||
= [p(_jn0|f1,a1).π_Jn(a1) + p(_jn0|f1,a2).π_Jn(a2)].λ(_jn0)
|
||||
+ [p(_jn1|f1,a1).π_Jn(a1) + p(_jn1|f1,a2).π_Jn(a2)].λ(_jn1)
|
||||
+ [p(_jn2|f1,a1).π_Jn(a1) + p(_jn2|f1,a2).π_Jn(a2)].λ(_jn2)
|
||||
+ [p(_jn3|f1,a1).π_Jn(a1) + p(_jn3|f1,a2).π_Jn(a2)].λ(_jn3)
|
||||
= [(1x0.0138158) + (0x0.986184)]x1
|
||||
+ [(0x0.0138158) + (1x0.986184)]x1
|
||||
+ [(0x0.0138158) + (0x0.986184)]x1
|
||||
+ [(0x0.0138158) + (0x0.986184)]x1 = 1
|
||||
λ_Jn(f2)
|
||||
= [p(_jn0|f2,a1).π_Jn(a1) + p(_jn0|f2,a2).π_Jn(a2)].λ(_jn0)
|
||||
+ [p(_jn1|f2,a1).π_Jn(a1) + p(_jn1|f2,a2).π_Jn(a2)].λ(_jn1)
|
||||
+ [p(_jn2|f2,a1).π_Jn(a1) + p(_jn2|f2,a2).π_Jn(a2)].λ(_jn2)
|
||||
+ [p(_jn3|f2,a1).π_Jn(a1) + p(_jn3|f2,a2).π_Jn(a2)].λ(_jn3)
|
||||
= [(0x0.0138158) + (0x0.986184)]x1
|
||||
+ [(0x0.0138158) + (0x0.986184)]x1
|
||||
+ [(1x0.0138158) + (0x0.986184)]x1
|
||||
+ [(0x0.0138158) + (1x0.986184)]x1 = 1
|
||||
|
||||
λ message _Jn --> Alarm
|
||||
λ_Jn(a1)
|
||||
= [p(_jn0|f1,a1).π_Jn(f1) + p(_jn0|f2,a1).π_Jn(f2)].λ(_jn0)
|
||||
+ [p(_jn1|f1,a1).π_Jn(f1) + p(_jn1|f2,a1).π_Jn(f2)].λ(_jn1)
|
||||
+ [p(_jn2|f1,a1).π_Jn(f1) + p(_jn2|f2,a1).π_Jn(f2)].λ(_jn2)
|
||||
+ [p(_jn3|f1,a1).π_Jn(f1) + p(_jn3|f2,a1).π_Jn(f2)].λ(_jn3)
|
||||
= [(1x0.03) + (0x0.97)]x1
|
||||
+ [(0x0.03) + (0x0.97)]x1
|
||||
+ [(0x0.03) + (1x0.97)]x1
|
||||
+ [(0x0.03) + (0x0.97)]x1 = 1
|
||||
λ_Jn(a2)
|
||||
= [p(_jn0|f1,a2).π_Jn(f1) + p(_jn0|f2,a2).π_Jn(f2)].λ(_jn0)
|
||||
+ [p(_jn1|f1,a2).π_Jn(f1) + p(_jn1|f2,a2).π_Jn(f2)].λ(_jn1)
|
||||
+ [p(_jn2|f1,a2).π_Jn(f1) + p(_jn2|f2,a2).π_Jn(f2)].λ(_jn2)
|
||||
+ [p(_jn3|f1,a2).π_Jn(f1) + p(_jn3|f2,a2).π_Jn(f2)].λ(_jn3)
|
||||
= [(0x0.03) + (0x0.97)]x1
|
||||
+ [(1x0.03) + (0x0.97)]x1
|
||||
+ [(0x0.03) + (0x0.97)]x1
|
||||
+ [(0x0.03) + (1x0.97)]x1 = 1
|
||||
|
||||
π message Burglar --> Alarm
|
||||
πAlarm(b1) = π(b1) = 0.005 = 0.005
|
||||
πAlarm(b2) = π(b2) = 0.995 = 0.995
|
||||
|
||||
π message FreightTruck --> Alarm
|
||||
πAlarm(f1) = π(f1).λ_Jn(f1) = 0.03 x 0.5 = 0.015
|
||||
πAlarm(f2) = π(f2).λ_Jn(f2) = 0.97 x 0.5 = 0.485
|
||||
|
||||
π message FreightTruck --> _Jn
|
||||
π_Jn(f1) = π(f1).λAlarm(f1) = 0.03 x 0.5 = 0.015
|
||||
π_Jn(f2) = π(f2).λAlarm(f2) = 0.97 x 0.5 = 0.485
|
||||
|
||||
π message Alarm --> _Jn
|
||||
π_Jn(a1) = π(a1) = 0.0138158 = 0.01381575
|
||||
π_Jn(a2) = π(a2) = 0.986184 = 0.98618425
|
||||
|
||||
var Burglar:
|
||||
π(b1)
|
||||
= p(b1)
|
||||
= (0.005) = 0.005
|
||||
π(b2)
|
||||
= p(b2)
|
||||
= (0.995) = 0.995
|
||||
λ(b1) = λAlarm(b1) = 0.5 = 0.5
|
||||
λ(b2) = λAlarm(b2) = 0.5 = 0.5
|
||||
belief change = 0
|
||||
|
||||
var FreightTruck:
|
||||
π(f1)
|
||||
= p(f1)
|
||||
= (0.03) = 0.03
|
||||
π(f2)
|
||||
= p(f2)
|
||||
= (0.97) = 0.97
|
||||
λ(f1) = λAlarm(f1).λ_Jn(f1) = 0.5 x 0.5 = 0.25
|
||||
λ(f2) = λAlarm(f2).λ_Jn(f2) = 0.5 x 0.5 = 0.25
|
||||
belief change = 0
|
||||
|
||||
var Alarm:
|
||||
π(a1)
|
||||
= p(a1|b1,f1).πAlarm(b1).πAlarm(f1)
|
||||
+ p(a1|b1,f2).πAlarm(b1).πAlarm(f2)
|
||||
+ p(a1|b2,f1).πAlarm(b2).πAlarm(f1)
|
||||
+ p(a1|b2,f2).πAlarm(b2).πAlarm(f2)
|
||||
= (0.992x0.005x0.03)
|
||||
+ (0.99x0.005x0.97)
|
||||
+ (0.2x0.995x0.03)
|
||||
+ (0.003x0.995x0.97) = 0.01381575
|
||||
π(a2)
|
||||
= p(a2|b1,f1).πAlarm(b1).πAlarm(f1)
|
||||
+ p(a2|b1,f2).πAlarm(b1).πAlarm(f2)
|
||||
+ p(a2|b2,f1).πAlarm(b2).πAlarm(f1)
|
||||
+ p(a2|b2,f2).πAlarm(b2).πAlarm(f2)
|
||||
= (0.008x0.005x0.03)
|
||||
+ (0.01x0.005x0.97)
|
||||
+ (0.8x0.995x0.03)
|
||||
+ (0.997x0.995x0.97) = 0.98618425
|
||||
λ(a1) = λ_Jn(a1) = 0.5 = 0.5
|
||||
λ(a2) = λ_Jn(a2) = 0.5 = 0.5
|
||||
belief change = 0
|
||||
|
||||
var _Jn:
|
||||
π(_jn0)
|
||||
= p(_jn0|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn0|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn0|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn0|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (1x0.03x0.0138158)
|
||||
+ (0x0.03x0.986184)
|
||||
+ (0x0.97x0.0138158)
|
||||
+ (0x0.97x0.986184) = 0.0004144725
|
||||
π(_jn1)
|
||||
= p(_jn1|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn1|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn1|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn1|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (0x0.03x0.0138158)
|
||||
+ (1x0.03x0.986184)
|
||||
+ (0x0.97x0.0138158)
|
||||
+ (0x0.97x0.986184) = 0.0295855275
|
||||
π(_jn2)
|
||||
= p(_jn2|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn2|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn2|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn2|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (0x0.03x0.0138158)
|
||||
+ (0x0.03x0.986184)
|
||||
+ (1x0.97x0.0138158)
|
||||
+ (0x0.97x0.986184) = 0.0134012775
|
||||
π(_jn3)
|
||||
= p(_jn3|f1,a1).π_Jn(f1).π_Jn(a1)
|
||||
+ p(_jn3|f1,a2).π_Jn(f1).π_Jn(a2)
|
||||
+ p(_jn3|f2,a1).π_Jn(f2).π_Jn(a1)
|
||||
+ p(_jn3|f2,a2).π_Jn(f2).π_Jn(a2)
|
||||
= (0x0.03x0.0138158)
|
||||
+ (0x0.03x0.986184)
|
||||
+ (0x0.97x0.0138158)
|
||||
+ (1x0.97x0.986184) = 0.9565987225
|
||||
λ(_jn0) = 1
|
||||
λ(_jn1) = 1
|
||||
λ(_jn2) = 1
|
||||
λ(_jn3) = 1
|
||||
belief change = 0
|
||||
|
||||
domain π(Burglar) λ(Burglar) belief
|
||||
----------------------------------------------------------------
|
||||
b1 0.005 0.5 0.005
|
||||
b2 0.995 0.5 0.995
|
||||
|
||||
domain πAlarm(Burglar) λAlarm(Burglar)
|
||||
----------------------------------------------------------------
|
||||
b1 0.005 0.5
|
||||
b2 0.995 0.5
|
||||
|
||||
domain π(FreightTruck) λ(FreightTruck) belief
|
||||
----------------------------------------------------------------
|
||||
f1 0.03 0.25 0.03
|
||||
f2 0.97 0.25 0.97
|
||||
|
||||
domain πAlarm(FreightTruck) λAlarm(FreightTruck)
|
||||
----------------------------------------------------------------
|
||||
f1 0.03 0.5
|
||||
f2 0.97 0.5
|
||||
|
||||
domain π_Jn(FreightTruck) λ_Jn(FreightTruck)
|
||||
----------------------------------------------------------------
|
||||
f1 0.03 0.5
|
||||
f2 0.97 0.5
|
||||
|
||||
domain π(Alarm) λ(Alarm) belief
|
||||
----------------------------------------------------------------
|
||||
a1 0.01381575 0.5 0.01381575
|
||||
a2 0.98618425 0.5 0.98618425
|
||||
|
||||
domain π_Jn(Alarm) λ_Jn(Alarm)
|
||||
----------------------------------------------------------------
|
||||
a1 0.01381575 0.5
|
||||
a2 0.98618425 0.5
|
||||
|
||||
domain π(_Jn) λ(_Jn) belief
|
||||
----------------------------------------------------------------
|
||||
_jn0 0.0004144725 1 0.0004144725
|
||||
_jn1 0.0295855275 1 0.0295855275
|
||||
_jn2 0.0134012775 1 0.0134012775
|
||||
_jn3 0.9565987225 1 0.9565987225
|
||||
|
||||
|
||||
Iterative belief propagation converged in 3 iterations
|
||||
|
10366
packages/CLPBN/clpbn/bp/simple-loop.par.txt
Normal file
10366
packages/CLPBN/clpbn/bp/simple-loop.par.txt
Normal file
File diff suppressed because it is too large
Load Diff
85
packages/CLPBN/clpbn/bp/simple-loop.seq.txt
Normal file
85
packages/CLPBN/clpbn/bp/simple-loop.seq.txt
Normal file
@ -0,0 +1,85 @@
|
||||
Variable: A
|
||||
Domain: a1, a2
|
||||
Parents:
|
||||
Childs: B, C
|
||||
cpt
|
||||
----------------
|
||||
a1 0.01
|
||||
a2 0.09
|
||||
|
||||
Variable: B
|
||||
Domain: b1, b2
|
||||
Parents: A
|
||||
Childs: D
|
||||
cpt a1, a2,
|
||||
----------------------------
|
||||
b1 0.03 0.6
|
||||
b2 0.97 0.4
|
||||
|
||||
Variable: C
|
||||
Domain: c1, c2
|
||||
Parents: A
|
||||
Childs: D
|
||||
cpt a1, a2,
|
||||
----------------------------
|
||||
c1 0.24 0.12
|
||||
c2 0.76 0.88
|
||||
|
||||
Variable: D
|
||||
Domain: d1, d2
|
||||
Parents: B, C
|
||||
Childs:
|
||||
cpt b1,c1, b1,c2, b2,c1, b2,c2,
|
||||
----------------------------------------------------
|
||||
d1 0.2 0.7 0.45 0.22
|
||||
d2 0.8 0.3 0.55 0.78
|
||||
|
||||
initializing solver
|
||||
schedule = sequential
|
||||
maxIter = 100
|
||||
accuracy = 0
|
||||
sending pi message from `A' to `B'
|
||||
πB(a1) = π(a1).λC(a1) = 0.01 x 1 = 0.01
|
||||
πB(a2) = π(a2).λC(a2) = 0.09 x 1 = 0.09
|
||||
π(b1) = p(b1|a1).πB(a1) + p(b1|a2).πB(a2) = (0.03 x 0.01) + (0.6 x 0.09) = 0.0543
|
||||
π(b2) = p(b2|a1).πB(a1) + p(b2|a2).πB(a2) = (0.97 x 0.01) + (0.4 x 0.09) = 0.0457
|
||||
sending pi message from `B' to `D'
|
||||
πD(b1) = π(b1) = 0.0543 = 0.0543
|
||||
πD(b2) = π(b2) = 0.0457 = 0.0457
|
||||
π(d1) = p(d1|b1,c1).πD(b1).πD(c1) + p(d1|b1,c2).πD(b1).πD(c2) + p(d1|b2,c1).πD(b2).πD(c1) + p(d1|b2,c2).πD(b2).πD(c2) = (0.2 x 0.0543 x 1) + (0.7 x 0.0543 x 1) + (0.45 x 0.0457 x 1) + (0.22 x 0.0457 x 1) = 0.079489
|
||||
π(d2) = p(d2|b1,c1).πD(b1).πD(c1) + p(d2|b1,c2).πD(b1).πD(c2) + p(d2|b2,c1).πD(b2).πD(c1) + p(d2|b2,c2).πD(b2).πD(c2) = (0.8 x 0.0543 x 1) + (0.3 x 0.0543 x 1) + (0.55 x 0.0457 x 1) + (0.78 x 0.0457 x 1) = 0.120511
|
||||
sending pi message from `A' to `C'
|
||||
πC(a1) = π(a1).λB(a1) = 0.01 x 1 = 0.01
|
||||
πC(a2) = π(a2).λB(a2) = 0.09 x 1 = 0.09
|
||||
π(c1) = p(c1|a1).πC(a1) + p(c1|a2).πC(a2) = (0.24 x 0.01) + (0.12 x 0.09) = 0.0132
|
||||
π(c2) = p(c2|a1).πC(a1) + p(c2|a2).πC(a2) = (0.76 x 0.01) + (0.88 x 0.09) = 0.0868
|
||||
sending pi message from `C' to `D'
|
||||
πD(c1) = π(c1) = 0.0132 = 0.0132
|
||||
πD(c2) = π(c2) = 0.0868 = 0.0868
|
||||
π(d1) = p(d1|b1,c1).πD(b1).πD(c1) + p(d1|b1,c2).πD(b1).πD(c2) + p(d1|b2,c1).πD(b2).πD(c1) + p(d1|b2,c2).πD(b2).πD(c2) = (0.2 x 0.0543 x 0.0132) + (0.7 x 0.0543 x 0.0868) + (0.45 x 0.0457 x 0.0132) + (0.22 x 0.0457 x 0.0868) = 0.00458677
|
||||
π(d2) = p(d2|b1,c1).πD(b1).πD(c1) + p(d2|b1,c2).πD(b1).πD(c2) + p(d2|b2,c1).πD(b2).πD(c1) + p(d2|b2,c2).πD(b2).πD(c2) = (0.8 x 0.0543 x 0.0132) + (0.3 x 0.0543 x 0.0868) + (0.55 x 0.0457 x 0.0132) + (0.78 x 0.0457 x 0.0868) = 0.00541323
|
||||
|
||||
beliefs for variable `A':
|
||||
domain belief
|
||||
----------------------------------
|
||||
a1 0.1
|
||||
a2 0.9
|
||||
|
||||
beliefs for variable `B':
|
||||
domain belief
|
||||
----------------------------------
|
||||
b1 0.543
|
||||
b2 0.457
|
||||
|
||||
beliefs for variable `C':
|
||||
domain belief
|
||||
----------------------------------
|
||||
c1 0.132
|
||||
c2 0.868
|
||||
|
||||
beliefs for variable `D':
|
||||
domain belief
|
||||
----------------------------------
|
||||
d1 0.45867652
|
||||
d2 0.54132348
|
||||
|
241
packages/CLPBN/clpbn/bp/xmlParser/AFPL-license.txt
Normal file
241
packages/CLPBN/clpbn/bp/xmlParser/AFPL-license.txt
Normal file
@ -0,0 +1,241 @@
|
||||
Aladdin Free Public License
|
||||
(Version 8, November 18, 1999)
|
||||
|
||||
Copyright (C) 1994, 1995, 1997, 1998, 1999 Aladdin Enterprises,
|
||||
Menlo Park, California, U.S.A. All rights reserved.
|
||||
|
||||
*NOTE:* This License is not the same as any of the GNU Licenses
|
||||
<http://www.gnu.org/copyleft/gpl.html> published by the Free
|
||||
Software Foundation <http://www.gnu.org/>. Its terms are
|
||||
substantially different from those of the GNU Licenses. If you are
|
||||
familiar with the GNU Licenses, please read this license with extra
|
||||
care.
|
||||
|
||||
Aladdin Enterprises hereby grants to anyone the permission to apply this
|
||||
License to their own work, as long as the entire License (including the
|
||||
above notices and this paragraph) is copied with no changes, additions,
|
||||
or deletions except for changing the first paragraph of Section 0 to
|
||||
include a suitable description of the work to which the license is being
|
||||
applied and of the person or entity that holds the copyright in the
|
||||
work, and, if the License is being applied to a work created in a
|
||||
country other than the United States, replacing the first paragraph of
|
||||
Section 6 with an appropriate reference to the laws of the appropriate
|
||||
country.
|
||||
|
||||
|
||||
0. Subject Matter
|
||||
|
||||
This License applies to the computer program known as "XMLParser library".
|
||||
The "Program", below, refers to such program. The Program
|
||||
is a copyrighted work whose copyright is held by Frank Vanden Berghen
|
||||
(the "Licensor").
|
||||
|
||||
A "work based on the Program" means either the Program or any derivative
|
||||
work of the Program, as defined in the United States Copyright Act of
|
||||
1976, such as a translation or a modification.
|
||||
|
||||
* BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE
|
||||
PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL
|
||||
ITS TERMS AND CONDITIONS FOR COPYING, DISTRIBUTING OR MODIFYING THE
|
||||
PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS YOU
|
||||
PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE WORKS.
|
||||
THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE TERMS
|
||||
AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM. *
|
||||
|
||||
|
||||
1. Licenses.
|
||||
|
||||
Licensor hereby grants you the following rights, provided that you
|
||||
comply with all of the restrictions set forth in this License and
|
||||
provided, further, that you distribute an unmodified copy of this
|
||||
License with the Program:
|
||||
|
||||
(a)
|
||||
You may copy and distribute literal (i.e., verbatim) copies of the
|
||||
Program's source code as you receive it throughout the world, in any
|
||||
medium.
|
||||
(b)
|
||||
You may modify the Program, create works based on the Program and
|
||||
distribute copies of such throughout the world, in any medium.
|
||||
|
||||
|
||||
2. Restrictions.
|
||||
|
||||
This license is subject to the following restrictions:
|
||||
|
||||
(a)
|
||||
Distribution of the Program or any work based on the Program by a
|
||||
commercial organization to any third party is prohibited if any
|
||||
payment is made in connection with such distribution, whether
|
||||
directly (as in payment for a copy of the Program) or indirectly (as
|
||||
in payment for some service related to the Program, or payment for
|
||||
some product or service that includes a copy of the Program "without
|
||||
charge"; these are only examples, and not an exhaustive enumeration
|
||||
of prohibited activities). The following methods of distribution
|
||||
involving payment shall not in and of themselves be a violation of
|
||||
this restriction:
|
||||
|
||||
(i)
|
||||
Posting the Program on a public access information storage and
|
||||
retrieval service for which a fee is received for retrieving
|
||||
information (such as an on-line service), provided that the fee
|
||||
is not content-dependent (i.e., the fee would be the same for
|
||||
retrieving the same volume of information consisting of random
|
||||
data) and that access to the service and to the Program is
|
||||
available independent of any other product or service. An
|
||||
example of a service that does not fall under this section is an
|
||||
on-line service that is operated by a company and that is only
|
||||
available to customers of that company. (This is not an
|
||||
exhaustive enumeration.)
|
||||
(ii)
|
||||
Distributing the Program on removable computer-readable media,
|
||||
provided that the files containing the Program are reproduced
|
||||
entirely and verbatim on such media, that all information on
|
||||
such media be redistributable for non-commercial purposes
|
||||
without charge, and that such media are distributed by
|
||||
themselves (except for accompanying documentation) independent
|
||||
of any other product or service. Examples of such media include
|
||||
CD-ROM, magnetic tape, and optical storage media. (This is not
|
||||
intended to be an exhaustive list.) An example of a distribution
|
||||
that does not fall under this section is a CD-ROM included in a
|
||||
book or magazine. (This is not an exhaustive enumeration.)
|
||||
|
||||
(b)
|
||||
Activities other than copying, distribution and modification of the
|
||||
Program are not subject to this License and they are outside its
|
||||
scope. Functional use (running) of the Program is not restricted,
|
||||
and any output produced through the use of the Program is subject to
|
||||
this license only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
(c)
|
||||
You must meet all of the following conditions with respect to any
|
||||
work that you distribute or publish that in whole or in part
|
||||
contains or is derived from the Program or any part thereof ("the
|
||||
Work"):
|
||||
|
||||
(i)
|
||||
If you have modified the Program, you must cause the Work to
|
||||
carry prominent notices stating that you have modified the
|
||||
Program's files and the date of any change. In each source file
|
||||
that you have modified, you must include a prominent notice that
|
||||
you have modified the file, including your name, your e-mail
|
||||
address (if any), and the date and purpose of the change;
|
||||
(ii)
|
||||
You must cause the Work to be licensed as a whole and at no
|
||||
charge to all third parties under the terms of this License;
|
||||
(iii)
|
||||
If the Work normally reads commands interactively when run, you
|
||||
must cause it, at each time the Work commences operation, to
|
||||
print or display an announcement including an appropriate
|
||||
copyright notice and a notice that there is no warranty (or
|
||||
else, saying that you provide a warranty). Such notice must also
|
||||
state that users may redistribute the Work only under the
|
||||
conditions of this License and tell the user how to view the
|
||||
copy of this License included with the Work. (Exceptions: if the
|
||||
Program is interactive but normally prints or displays such an
|
||||
announcement only at the request of a user, such as in an "About
|
||||
box", the Work is required to print or display the notice only
|
||||
under the same circumstances; if the Program itself is
|
||||
interactive but does not normally print such an announcement,
|
||||
the Work is not required to print an announcement.);
|
||||
(iv)
|
||||
You must accompany the Work with the complete corresponding
|
||||
machine-readable source code, delivered on a medium customarily
|
||||
used for software interchange. The source code for a work means
|
||||
the preferred form of the work for making modifications to it.
|
||||
For an executable work, complete source code means all the
|
||||
source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control
|
||||
compilation and installation of the executable code. If you
|
||||
distribute with the Work any component that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system
|
||||
on which the executable runs, you must also distribute the
|
||||
source code of that component if you have it and are allowed to
|
||||
do so;
|
||||
(v)
|
||||
If you distribute any written or printed material at all with
|
||||
the Work, such material must include either a written copy of
|
||||
this License, or a prominent written indication that the Work is
|
||||
covered by this License and written instructions for printing
|
||||
and/or displaying the copy of the License on the distribution
|
||||
medium;
|
||||
(vi)
|
||||
You may not impose any further restrictions on the recipient's
|
||||
exercise of the rights granted herein.
|
||||
|
||||
If distribution of executable or object code is made by offering the
|
||||
equivalent ability to copy from a designated place, then offering
|
||||
equivalent ability to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source code along with the object code.
|
||||
|
||||
|
||||
3. Reservation of Rights.
|
||||
|
||||
No rights are granted to the Program except as expressly set forth
|
||||
herein. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt otherwise
|
||||
to copy, modify, sublicense or distribute the Program is void, and will
|
||||
automatically terminate your rights under this License. However, parties
|
||||
who have received copies, or rights, from you under this License will
|
||||
not have their licenses terminated so long as such parties remain in
|
||||
full compliance.
|
||||
|
||||
|
||||
4. Other Restrictions.
|
||||
|
||||
If the distribution and/or use of the Program is restricted in certain
|
||||
countries for any reason, Licensor may add an explicit geographical
|
||||
distribution limitation excluding those countries, so that distribution
|
||||
is permitted only in or among countries not thus excluded. In such case,
|
||||
this License incorporates the limitation as if written in the body of
|
||||
this License.
|
||||
|
||||
|
||||
5. Limitations.
|
||||
|
||||
* THE PROGRAM IS PROVIDED TO YOU "AS IS," WITHOUT WARRANTY. THERE IS NO
|
||||
WARRANTY FOR THE PROGRAM, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
|
||||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE
|
||||
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
|
||||
YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||
NECESSARY SERVICING, REPAIR OR CORRECTION. *
|
||||
|
||||
* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL LICENSOR, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
|
||||
PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS
|
||||
OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
|
||||
THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES. *
|
||||
|
||||
|
||||
6. General.
|
||||
|
||||
This License is governed by the laws of Belgium., excluding choice of
|
||||
law rules.
|
||||
|
||||
If any part of this License is found to be in conflict with the law,
|
||||
that part shall be interpreted in its broadest meaning consistent with
|
||||
the law, and no other parts of the License shall be affected.
|
||||
|
||||
For United States Government users, the Program is provided with
|
||||
*RESTRICTED RIGHTS*. If you are a unit or agency of the United States
|
||||
Government or are acquiring the Program for any such unit or agency, the
|
||||
following apply:
|
||||
|
||||
If the unit or agency is the Department of Defense ("DOD"), the
|
||||
Program and its documentation are classified as "commercial computer
|
||||
software" and "commercial computer software documentation"
|
||||
respectively and, pursuant to DFAR Section 227.7202, the Government
|
||||
is acquiring the Program and its documentation in accordance with
|
||||
the terms of this License. If the unit or agency is other than DOD,
|
||||
the Program and its documentation are classified as "commercial
|
||||
computer software" and "commercial computer software documentation"
|
||||
respectively and, pursuant to FAR Section 12.212, the Government is
|
||||
acquiring the Program and its documentation in accordance with the
|
||||
terms of this License.
|
2936
packages/CLPBN/clpbn/bp/xmlParser/xmlParser.cpp
Normal file
2936
packages/CLPBN/clpbn/bp/xmlParser/xmlParser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
734
packages/CLPBN/clpbn/bp/xmlParser/xmlParser.h
Normal file
734
packages/CLPBN/clpbn/bp/xmlParser/xmlParser.h
Normal file
@ -0,0 +1,734 @@
|
||||
|
||||
/****************************************************************************/
|
||||
/*! \mainpage XMLParser library
|
||||
* \section intro_sec Introduction
|
||||
*
|
||||
* This is a basic XML parser written in ANSI C++ for portability.
|
||||
* It works by using recursion and a node tree for breaking
|
||||
* down the elements of an XML document.
|
||||
*
|
||||
* @version V2.42
|
||||
* @author Frank Vanden Berghen
|
||||
*
|
||||
* Copyright (c) 2002, Business-Insight
|
||||
* <a href="http://www.Business-Insight.com">Business-Insight</a>
|
||||
* All rights reserved.
|
||||
* See the file <a href="../../AFPL-license.txt">AFPL-license.txt</a> about the licensing terms
|
||||
*
|
||||
* \section tutorial First Tutorial
|
||||
* You can follow a simple <a href="../../xmlParser.html">Tutorial</a> to know the basics...
|
||||
*
|
||||
* \section usage General usage: How to include the XMLParser library inside your project.
|
||||
*
|
||||
* The library is composed of two files: <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
|
||||
* <a href="../../xmlParser.h">xmlParser.h</a>. These are the ONLY 2 files that you need when
|
||||
* using the library inside your own projects.
|
||||
*
|
||||
* All the functions of the library are documented inside the comments of the file
|
||||
* <a href="../../xmlParser.h">xmlParser.h</a>. These comments can be transformed in
|
||||
* full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg"
|
||||
*
|
||||
* By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*)
|
||||
* version of the library, you need to define the "_UNICODE" preprocessor definition variable
|
||||
* (this is usually done inside your project definition file) (This is done automatically for you
|
||||
* when using Visual Studio).
|
||||
*
|
||||
* \section example Advanced Tutorial and Many Examples of usage.
|
||||
*
|
||||
* Some very small introductory examples are described inside the Tutorial file
|
||||
* <a href="../../xmlParser.html">xmlParser.html</a>
|
||||
*
|
||||
* Some additional small examples are also inside the file <a href="../../xmlTest.cpp">xmlTest.cpp</a>
|
||||
* (for the "char*" version of the library) and inside the file
|
||||
* <a href="../../xmlTestUnicode.cpp">xmlTestUnicode.cpp</a> (for the "wchar_t*"
|
||||
* version of the library). If you have a question, please review these additionnal examples
|
||||
* before sending an e-mail to the author.
|
||||
*
|
||||
* To build the examples:
|
||||
* - linux/unix: type "make"
|
||||
* - solaris: type "make -f makefile.solaris"
|
||||
* - windows: Visual Studio: double-click on xmlParser.dsw
|
||||
* (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files)
|
||||
*
|
||||
* In order to build the examples you need some additional files:
|
||||
* - linux/unix: makefile
|
||||
* - solaris: makefile.solaris
|
||||
* - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll
|
||||
*
|
||||
* \section debugging Debugging with the XMLParser library
|
||||
*
|
||||
* \subsection debugwin Debugging under WINDOWS
|
||||
*
|
||||
* Inside Visual C++, the "debug versions" of the memory allocation functions are
|
||||
* very slow: Do not forget to compile in "release mode" to get maximum speed.
|
||||
* When I had to debug a software that was using the XMLParser Library, it was usually
|
||||
* a nightmare because the library was sooOOOoooo slow in debug mode (because of the
|
||||
* slow memory allocations in Debug mode). To solve this
|
||||
* problem, during all the debugging session, I am now using a very fast DLL version of the
|
||||
* XMLParser Library (the DLL is compiled in release mode). Using the DLL version of
|
||||
* the XMLParser Library allows me to have lightening XML parsing speed even in debug!
|
||||
* Other than that, the DLL version is useless: In the release version of my tool,
|
||||
* I always use the normal, ".cpp"-based, XMLParser Library (I simply include the
|
||||
* <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
|
||||
* <a href="../../xmlParser.h">xmlParser.h</a> files into the project).
|
||||
*
|
||||
* The file <a href="../../XMLNodeAutoexp.txt">XMLNodeAutoexp.txt</a> contains some
|
||||
* "tweaks" that improve substancially the display of the content of the XMLNode objects
|
||||
* inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger
|
||||
* the "smooth" display of the XMLNode objects, you cannot live without it anymore!
|
||||
*
|
||||
* \subsection debuglinux Debugging under LINUX/UNIX
|
||||
*
|
||||
* The speed of the debug version of the XMLParser library is tolerable so no extra
|
||||
* work.has been done.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_XML_NODE__
|
||||
#define __INCLUDE_XML_NODE__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _UNICODE
|
||||
// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
|
||||
// This is useful when you get error messages like:
|
||||
// 'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
|
||||
// The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
|
||||
// must be defined) or utf8-mode(the pre-processor variable must be undefined).
|
||||
#define _XMLWIDECHAR
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__)
|
||||
// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland
|
||||
#define _XMLWINDOWS
|
||||
#endif
|
||||
|
||||
#ifdef XMLDLLENTRY
|
||||
#undef XMLDLLENTRY
|
||||
#endif
|
||||
#ifdef _USE_XMLPARSER_DLL
|
||||
#ifdef _DLL_EXPORTS_
|
||||
#define XMLDLLENTRY __declspec(dllexport)
|
||||
#else
|
||||
#define XMLDLLENTRY __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define XMLDLLENTRY
|
||||
#endif
|
||||
|
||||
// uncomment the next line if you want no support for wchar_t* (no need for the <wchar.h> or <tchar.h> libraries anymore to compile)
|
||||
//#define XML_NO_WIDE_CHAR
|
||||
|
||||
#ifdef XML_NO_WIDE_CHAR
|
||||
#undef _XMLWINDOWS
|
||||
#undef _XMLWIDECHAR
|
||||
#endif
|
||||
|
||||
#ifdef _XMLWINDOWS
|
||||
#include <tchar.h>
|
||||
#else
|
||||
#define XMLDLLENTRY
|
||||
#ifndef XML_NO_WIDE_CHAR
|
||||
#include <wchar.h> // to have 'wcsrtombs' for ANSI version
|
||||
// to have 'mbsrtowcs' for WIDECHAR version
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Some common types for char set portable code
|
||||
#ifdef _XMLWIDECHAR
|
||||
#define _CXML(c) L ## c
|
||||
#define XMLCSTR const wchar_t *
|
||||
#define XMLSTR wchar_t *
|
||||
#define XMLCHAR wchar_t
|
||||
#else
|
||||
#define _CXML(c) c
|
||||
#define XMLCSTR const char *
|
||||
#define XMLSTR char *
|
||||
#define XMLCHAR char
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* FALSE */
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* TRUE */
|
||||
|
||||
|
||||
/// Enumeration for XML parse errors.
|
||||
typedef enum XMLError
|
||||
{
|
||||
eXMLErrorNone = 0,
|
||||
eXMLErrorMissingEndTag,
|
||||
eXMLErrorNoXMLTagFound,
|
||||
eXMLErrorEmpty,
|
||||
eXMLErrorMissingTagName,
|
||||
eXMLErrorMissingEndTagName,
|
||||
eXMLErrorUnmatchedEndTag,
|
||||
eXMLErrorUnmatchedEndClearTag,
|
||||
eXMLErrorUnexpectedToken,
|
||||
eXMLErrorNoElements,
|
||||
eXMLErrorFileNotFound,
|
||||
eXMLErrorFirstTagNotFound,
|
||||
eXMLErrorUnknownCharacterEntity,
|
||||
eXMLErrorCharacterCodeAbove255,
|
||||
eXMLErrorCharConversionError,
|
||||
eXMLErrorCannotOpenWriteFile,
|
||||
eXMLErrorCannotWriteFile,
|
||||
|
||||
eXMLErrorBase64DataSizeIsNotMultipleOf4,
|
||||
eXMLErrorBase64DecodeIllegalCharacter,
|
||||
eXMLErrorBase64DecodeTruncatedData,
|
||||
eXMLErrorBase64DecodeBufferTooSmall
|
||||
} XMLError;
|
||||
|
||||
|
||||
/// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
|
||||
typedef enum XMLElementType
|
||||
{
|
||||
eNodeChild=0,
|
||||
eNodeAttribute=1,
|
||||
eNodeText=2,
|
||||
eNodeClear=3,
|
||||
eNodeNULL=4
|
||||
} XMLElementType;
|
||||
|
||||
/// Structure used to obtain error details if the parse fails.
|
||||
typedef struct XMLResults
|
||||
{
|
||||
enum XMLError error;
|
||||
int nLine,nColumn;
|
||||
} XMLResults;
|
||||
|
||||
/// Structure for XML clear (unformatted) node (usually comments)
|
||||
typedef struct XMLClear {
|
||||
XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag;
|
||||
} XMLClear;
|
||||
|
||||
/// Structure for XML attribute.
|
||||
typedef struct XMLAttribute {
|
||||
XMLCSTR lpszName; XMLCSTR lpszValue;
|
||||
} XMLAttribute;
|
||||
|
||||
/// XMLElementPosition are not interchangeable with simple indexes
|
||||
typedef int XMLElementPosition;
|
||||
|
||||
struct XMLNodeContents;
|
||||
|
||||
/** @defgroup XMLParserGeneral The XML parser */
|
||||
|
||||
/// Main Class representing a XML node
|
||||
/**
|
||||
* All operations are performed using this class.
|
||||
* \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode:
|
||||
* <ul>
|
||||
* <li> XMLNode::parseString </li>
|
||||
* <li> XMLNode::parseFile </li>
|
||||
* <li> XMLNode::openFileHelper </li>
|
||||
* <li> XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)</li>
|
||||
* </ul> */
|
||||
typedef struct XMLDLLENTRY XMLNode
|
||||
{
|
||||
private:
|
||||
|
||||
struct XMLNodeDataTag;
|
||||
|
||||
/// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
|
||||
XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration);
|
||||
/// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
|
||||
XMLNode(struct XMLNodeDataTag *p);
|
||||
|
||||
public:
|
||||
static XMLCSTR getVersion();///< Return the XMLParser library version number
|
||||
|
||||
/** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string.
|
||||
* @ingroup XMLParserGeneral
|
||||
* @{ */
|
||||
|
||||
/// Parse an XML string and return the root of a XMLNode tree representing the string.
|
||||
static XMLNode parseString (XMLCSTR lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
|
||||
/**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is
|
||||
* the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the
|
||||
* "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error.
|
||||
* If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
|
||||
* beginning of the "xmlParser.cpp" file.
|
||||
*
|
||||
* @param lpXMLString the XML string to parse
|
||||
* @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
|
||||
* @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
|
||||
*/
|
||||
|
||||
/// Parse an XML file and return the root of a XMLNode tree representing the file.
|
||||
static XMLNode parseFile (XMLCSTR filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
|
||||
/**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is
|
||||
* the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the
|
||||
* "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error.
|
||||
* If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
|
||||
* beginning of the "xmlParser.cpp" file.
|
||||
*
|
||||
* @param filename the path to the XML file to parse
|
||||
* @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
|
||||
* @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
|
||||
*/
|
||||
|
||||
/// Parse an XML file and return the root of a XMLNode tree representing the file. A very crude error checking is made. An attempt to guess the Char Encoding used in the file is made.
|
||||
static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag=NULL);
|
||||
/**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file.
|
||||
* This function also tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) based on the first 200 bytes of the file. Since each
|
||||
* application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files
|
||||
* and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
|
||||
* mechanism included inside the "openFileHelper" function).
|
||||
*
|
||||
* If the XML document is corrupted, the "openFileHelper" method will:
|
||||
* - display an error message on the console (or inside a messageBox for windows).
|
||||
* - stop execution (exit).
|
||||
*
|
||||
* I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse
|
||||
* the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file.
|
||||
*
|
||||
* @param filename the path of the XML file to parse.
|
||||
* @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
|
||||
*/
|
||||
|
||||
static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error
|
||||
|
||||
/// Create an XML string starting from the current XMLNode.
|
||||
XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const;
|
||||
/**< The returned string should be free'd using the "freeXMLString" function.
|
||||
*
|
||||
* If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element
|
||||
* with appropriate white spaces and carriage returns. if pnSize is given it returns the size in character of the string. */
|
||||
|
||||
/// Save the content of an xmlNode inside a file
|
||||
XMLError writeToFile(XMLCSTR filename,
|
||||
const char *encoding=NULL,
|
||||
char nFormat=1) const;
|
||||
/**< If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element with appropriate white spaces and carriage returns.
|
||||
* If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8".
|
||||
* If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS".
|
||||
* If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16".
|
||||
* If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup navigate Navigate the XMLNode structure
|
||||
* @ingroup XMLParserGeneral
|
||||
* @{ */
|
||||
XMLCSTR getName() const; ///< name of the node
|
||||
XMLCSTR getText(int i=0) const; ///< return ith text field
|
||||
int nText() const; ///< nbr of text field
|
||||
XMLNode getParentNode() const; ///< return the parent node
|
||||
XMLNode getChildNode(int i=0) const; ///< return ith child node
|
||||
XMLNode getChildNode(XMLCSTR name, int i) const; ///< return ith child node with specific name (return an empty node if failing). If i==-1, this returns the last XMLNode with the given name.
|
||||
XMLNode getChildNode(XMLCSTR name, int *i=NULL) const; ///< return next child node with specific name (return an empty node if failing)
|
||||
XMLNode getChildNodeWithAttribute(XMLCSTR tagName,
|
||||
XMLCSTR attributeName,
|
||||
XMLCSTR attributeValue=NULL,
|
||||
int *i=NULL) const; ///< return child node with specific name/attribute (return an empty node if failing)
|
||||
XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/');
|
||||
///< return the first child node with specific path
|
||||
XMLNode getChildNodeByPathNonConst(XMLSTR path, char createNodeIfMissing=0, XMLCHAR sep='/');
|
||||
///< return the first child node with specific path.
|
||||
|
||||
int nChildNode(XMLCSTR name) const; ///< return the number of child node with specific name
|
||||
int nChildNode() const; ///< nbr of child node
|
||||
XMLAttribute getAttribute(int i=0) const; ///< return ith attribute
|
||||
XMLCSTR getAttributeName(int i=0) const; ///< return ith attribute name
|
||||
XMLCSTR getAttributeValue(int i=0) const; ///< return ith attribute value
|
||||
char isAttributeSet(XMLCSTR name) const; ///< test if an attribute with a specific name is given
|
||||
XMLCSTR getAttribute(XMLCSTR name, int i) const; ///< return ith attribute content with specific name (return a NULL if failing)
|
||||
XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const; ///< return next attribute content with specific name (return a NULL if failing)
|
||||
int nAttribute() const; ///< nbr of attribute
|
||||
XMLClear getClear(int i=0) const; ///< return ith clear field (comments)
|
||||
int nClear() const; ///< nbr of clear field
|
||||
XMLNodeContents enumContents(XMLElementPosition i) const; ///< enumerate all the different contents (attribute,child,text, clear) of the current XMLNode. The order is reflecting the order of the original file/string. NOTE: 0 <= i < nElement();
|
||||
int nElement() const; ///< nbr of different contents for current node
|
||||
char isEmpty() const; ///< is this node Empty?
|
||||
char isDeclaration() const; ///< is this node a declaration <? .... ?>
|
||||
XMLNode deepCopy() const; ///< deep copy (duplicate/clone) a XMLNode
|
||||
static XMLNode emptyNode(); ///< return XMLNode::emptyXMLNode;
|
||||
/** @} */
|
||||
|
||||
~XMLNode();
|
||||
XMLNode(const XMLNode &A); ///< to allow shallow/fast copy:
|
||||
XMLNode& operator=( const XMLNode& A ); ///< to allow shallow/fast copy:
|
||||
|
||||
XMLNode(): d(NULL){};
|
||||
static XMLNode emptyXMLNode;
|
||||
static XMLClear emptyXMLClear;
|
||||
static XMLAttribute emptyXMLAttribute;
|
||||
|
||||
/** @defgroup xmlModify Create or Update the XMLNode structure
|
||||
* @ingroup XMLParserGeneral
|
||||
* The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top
|
||||
* node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives
|
||||
* the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos=-1) inserts at the
|
||||
* end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end). <br>
|
||||
*
|
||||
* REMARK: 0 <= pos < nChild()+nText()+nClear() <br>
|
||||
*/
|
||||
|
||||
/** @defgroup creation Creating from scratch a XMLNode structure
|
||||
* @ingroup xmlModify
|
||||
* @{ */
|
||||
static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure
|
||||
XMLNode addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node
|
||||
XMLNode addChild(XMLNode nodeToAdd, XMLElementPosition pos=-1); ///< If the "nodeToAdd" has some parents, it will be detached from it's parents before being attached to the current XMLNode
|
||||
XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev); ///< Add a new attribute
|
||||
XMLCSTR addText(XMLCSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content
|
||||
XMLClear *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1);
|
||||
/**< Add a new clear tag
|
||||
* @param lpszOpen default value "<![CDATA["
|
||||
* @param lpszClose default value "]]>"
|
||||
*/
|
||||
/** @} */
|
||||
|
||||
/** @defgroup xmlUpdate Updating Nodes
|
||||
* @ingroup xmlModify
|
||||
* Some update functions:
|
||||
* @{
|
||||
*/
|
||||
XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name
|
||||
XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added
|
||||
XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0); ///< if the attribute to update is missing, a new one will be added
|
||||
XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
|
||||
XMLCSTR updateText(XMLCSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added
|
||||
XMLCSTR updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added
|
||||
XMLClear *updateClear(XMLCSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added
|
||||
XMLClear *updateClear(XMLClear *newP,XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added
|
||||
XMLClear *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added
|
||||
/** @} */
|
||||
|
||||
/** @defgroup xmlDelete Deleting Nodes or Attributes
|
||||
* @ingroup xmlModify
|
||||
* Some deletion functions:
|
||||
* @{
|
||||
*/
|
||||
/// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree.
|
||||
void deleteNodeContent();
|
||||
/**< \note The XMLNode instances that are referring to the part of the subtree that has been deleted CANNOT be used anymore!!. Unexpected results will occur if you continue using them. */
|
||||
void deleteAttribute(int i=0); ///< Delete the ith attribute of the current XMLNode
|
||||
void deleteAttribute(XMLCSTR lpszName); ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute)
|
||||
void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute)
|
||||
void deleteText(int i=0); ///< Delete the Ith text content of the current XMLNode
|
||||
void deleteText(XMLCSTR lpszValue); ///< Delete the text content "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the right text)
|
||||
void deleteClear(int i=0); ///< Delete the Ith clear tag inside the current XMLNode
|
||||
void deleteClear(XMLCSTR lpszValue); ///< Delete the clear tag "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the clear tag)
|
||||
void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the current XMLNode (direct "pointer-to-pointer" comparison on the lpszName of the clear tag is used to find the clear tag)
|
||||
/** @} */
|
||||
|
||||
/** @defgroup xmlWOSD ???_WOSD functions.
|
||||
* @ingroup xmlModify
|
||||
* The strings given as parameters for the "add" and "update" methods that have a name with
|
||||
* the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD")
|
||||
* will be free'd by the XMLNode class. For example, it means that this is incorrect:
|
||||
* \code
|
||||
* xNode.addText_WOSD("foo");
|
||||
* xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
|
||||
* \endcode
|
||||
* In opposition, this is correct:
|
||||
* \code
|
||||
* xNode.addText("foo");
|
||||
* xNode.addText_WOSD(stringDup("foo"));
|
||||
* xNode.updateAttribute("#newcolor" ,NULL,"color");
|
||||
* xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
|
||||
* \endcode
|
||||
* Typically, you will never do:
|
||||
* \code
|
||||
* char *b=(char*)malloc(...);
|
||||
* xNode.addText(b);
|
||||
* free(b);
|
||||
* \endcode
|
||||
* ... but rather:
|
||||
* \code
|
||||
* char *b=(char*)malloc(...);
|
||||
* xNode.addText_WOSD(b);
|
||||
* \endcode
|
||||
* ('free(b)' is performed by the XMLNode class)
|
||||
* @{ */
|
||||
static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure
|
||||
XMLNode addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node
|
||||
XMLAttribute *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue); ///< Add a new attribute
|
||||
XMLCSTR addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content
|
||||
XMLClear *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag
|
||||
|
||||
XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name
|
||||
XMLAttribute *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added
|
||||
XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL,int i=0); ///< if the attribute to update is missing, a new one will be added
|
||||
XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName); ///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
|
||||
XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added
|
||||
XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added
|
||||
XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added
|
||||
XMLClear *updateClear_WOSD(XMLClear *newP,XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added
|
||||
XMLClear *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added
|
||||
/** @} */
|
||||
|
||||
/** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions
|
||||
* @ingroup xmlModify
|
||||
* These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
|
||||
* middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
|
||||
* methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
|
||||
* @{ */
|
||||
XMLElementPosition positionOfText(int i=0) const;
|
||||
XMLElementPosition positionOfText(XMLCSTR lpszValue) const;
|
||||
XMLElementPosition positionOfClear(int i=0) const;
|
||||
XMLElementPosition positionOfClear(XMLCSTR lpszValue) const;
|
||||
XMLElementPosition positionOfClear(XMLClear *a) const;
|
||||
XMLElementPosition positionOfChildNode(int i=0) const;
|
||||
XMLElementPosition positionOfChildNode(XMLNode x) const;
|
||||
XMLElementPosition positionOfChildNode(XMLCSTR name, int i=0) const; ///< return the position of the ith childNode with the specified name if (name==NULL) return the position of the ith childNode
|
||||
/** @} */
|
||||
|
||||
/// Enumeration for XML character encoding.
|
||||
typedef enum XMLCharEncoding
|
||||
{
|
||||
char_encoding_error=0,
|
||||
char_encoding_UTF8=1,
|
||||
char_encoding_legacy=2,
|
||||
char_encoding_ShiftJIS=3,
|
||||
char_encoding_GB2312=4,
|
||||
char_encoding_Big5=5,
|
||||
char_encoding_GBK=6 // this is actually the same as Big5
|
||||
} XMLCharEncoding;
|
||||
|
||||
/** \addtogroup conversions
|
||||
* @{ */
|
||||
|
||||
/// Sets the global options for the conversions
|
||||
static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1,
|
||||
char dropWhiteSpace=1, char removeCommentsInMiddleOfText=1);
|
||||
/**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file
|
||||
* parsing. First of all, you most-probably will never have to change these 3 global parameters.
|
||||
*
|
||||
* @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the
|
||||
* XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII
|
||||
* characters. If this is the case, then the file will be loaded and converted in memory to
|
||||
* WideChar before being parsed. If 0, no conversion will be performed.
|
||||
*
|
||||
* @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the
|
||||
* XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar
|
||||
* characters. If this is the case, then the file will be loaded and converted in memory to
|
||||
* ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed.
|
||||
*
|
||||
* @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode).
|
||||
* In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the
|
||||
* three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii,
|
||||
* XMLNode::encoding_ShiftJIS.
|
||||
*
|
||||
* @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns)
|
||||
* are useless. Even more, these "empty" text fields are annoying because they increase the
|
||||
* complexity of the user's code for parsing. So, 99% of the time, it's better to drop
|
||||
* the "empty" text fields. However The XML specification indicates that no white spaces
|
||||
* should be lost when parsing the file. So to be perfectly XML-compliant, you should set
|
||||
* dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be
|
||||
* slower and your code will be more complex.
|
||||
*
|
||||
* @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code:
|
||||
* \code
|
||||
* XMLNode x=XMLNode::parseString("<a>foo<!-- hello -->bar<!DOCTYPE world >chu</a>","a");
|
||||
* \endcode
|
||||
* If removeCommentsInMiddleOfText=0, then we will have:
|
||||
* \code
|
||||
* x.getText(0) -> "foo"
|
||||
* x.getText(1) -> "bar"
|
||||
* x.getText(2) -> "chu"
|
||||
* x.getClear(0) --> "<!-- hello -->"
|
||||
* x.getClear(1) --> "<!DOCTYPE world >"
|
||||
* \endcode
|
||||
* If removeCommentsInMiddleOfText=1, then we will have:
|
||||
* \code
|
||||
* x.getText(0) -> "foobar"
|
||||
* x.getText(1) -> "chu"
|
||||
* x.getClear(0) --> "<!DOCTYPE world >"
|
||||
* \endcode
|
||||
*
|
||||
* \return "0" when there are no errors. If you try to set an unrecognized encoding then the return value will be "1" to signal an error.
|
||||
*
|
||||
* \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion
|
||||
* because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */
|
||||
|
||||
/// Guess the character encoding of the string (ascii, utf8 or shift-JIS)
|
||||
static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
|
||||
/**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never
|
||||
* have to use this function. It then returns the appropriate value of the global parameter
|
||||
* "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length
|
||||
* "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
|
||||
* file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute
|
||||
* the value of the "characterEncoding" global parameter. There are several heuristics used to do the
|
||||
* guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
|
||||
* forbids to use this attribute to do the guess but you can still use it if you set
|
||||
* "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
|
||||
* If an inconsistency in the encoding is detected, then the return value is "0". */
|
||||
/** @} */
|
||||
|
||||
private:
|
||||
// these are functions and structures used internally by the XMLNode class (don't bother about them):
|
||||
|
||||
typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
|
||||
{
|
||||
XMLCSTR lpszName; // Element name (=NULL if root)
|
||||
int nChild, // Number of child nodes
|
||||
nText, // Number of text fields
|
||||
nClear, // Number of Clear fields (comments)
|
||||
nAttribute; // Number of attributes
|
||||
char isDeclaration; // Whether node is an XML declaration - '<?xml ?>'
|
||||
struct XMLNodeDataTag *pParent; // Pointer to parent element (=NULL if root)
|
||||
XMLNode *pChild; // Array of child nodes
|
||||
XMLCSTR *pText; // Array of text fields
|
||||
XMLClear *pClear; // Array of clear fields
|
||||
XMLAttribute *pAttribute; // Array of attributes
|
||||
int *pOrder; // order of the child_nodes,text_fields,clear_fields
|
||||
int ref_count; // for garbage collection (smart pointers)
|
||||
} XMLNodeData;
|
||||
XMLNodeData *d;
|
||||
|
||||
char parseClearTag(void *px, void *pa);
|
||||
char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
|
||||
int ParseXMLElement(void *pXML);
|
||||
void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
|
||||
int indexText(XMLCSTR lpszValue) const;
|
||||
int indexClear(XMLCSTR lpszValue) const;
|
||||
XMLNode addChild_priv(int,XMLSTR,char,int);
|
||||
XMLAttribute *addAttribute_priv(int,XMLSTR,XMLSTR);
|
||||
XMLCSTR addText_priv(int,XMLSTR,int);
|
||||
XMLClear *addClear_priv(int,XMLSTR,XMLCSTR,XMLCSTR,int);
|
||||
void emptyTheNode(char force);
|
||||
static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype);
|
||||
static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
|
||||
static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
|
||||
static void exactMemory(XMLNodeData *d);
|
||||
static int detachFromParent(XMLNodeData *d);
|
||||
} XMLNode;
|
||||
|
||||
/// This structure is given by the function XMLNode::enumContents.
|
||||
typedef struct XMLNodeContents
|
||||
{
|
||||
/// This dictates what's the content of the XMLNodeContent
|
||||
enum XMLElementType etype;
|
||||
/**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */
|
||||
XMLNode child;
|
||||
XMLAttribute attrib;
|
||||
XMLCSTR text;
|
||||
XMLClear clear;
|
||||
|
||||
} XMLNodeContents;
|
||||
|
||||
/** @defgroup StringAlloc String Allocation/Free functions
|
||||
* @ingroup xmlModify
|
||||
* @{ */
|
||||
/// Duplicate (copy in a new allocated buffer) the source string.
|
||||
XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1);
|
||||
/**< This is
|
||||
* a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink).
|
||||
* @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with
|
||||
* this function should be free'd using the "freeXMLString" function. */
|
||||
|
||||
/// to free the string allocated inside the "stringDup" function or the "createXMLString" function.
|
||||
XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);}
|
||||
/** @} */
|
||||
|
||||
/** @defgroup atoX ato? like functions
|
||||
* @ingroup XMLParserGeneral
|
||||
* The "xmlto?" functions are equivalents to the atoi, atol, atof functions.
|
||||
* The only difference is: If the variable "xmlString" is NULL, than the return value
|
||||
* is "defautValue". These 6 functions are only here as "convenience" functions for the
|
||||
* user (they are not used inside the XMLparser). If you don't need them, you can
|
||||
* delete them without any trouble.
|
||||
*
|
||||
* @{ */
|
||||
XMLDLLENTRY char xmltob(XMLCSTR xmlString,char defautValue=0);
|
||||
XMLDLLENTRY int xmltoi(XMLCSTR xmlString,int defautValue=0);
|
||||
XMLDLLENTRY long xmltol(XMLCSTR xmlString,long defautValue=0);
|
||||
XMLDLLENTRY double xmltof(XMLCSTR xmlString,double defautValue=.0);
|
||||
XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString,XMLCSTR defautValue=_CXML(""));
|
||||
XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString,const XMLCHAR defautValue=_CXML('\0'));
|
||||
/** @} */
|
||||
|
||||
/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions.
|
||||
* @ingroup XMLParserGeneral
|
||||
* @{ */
|
||||
/// Helper class to create XML files using "printf", "fprintf", "cout",... functions.
|
||||
/** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions.
|
||||
* The "ToXMLStringTool" class is processing strings so that all the characters
|
||||
* &,",',<,> are replaced by their XML equivalent:
|
||||
* \verbatim &, ", ', <, > \endverbatim
|
||||
* Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient
|
||||
* way to produce VERY large XML documents VERY fast.
|
||||
* \note If you are creating from scratch an XML file using the provided XMLNode class
|
||||
* you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the
|
||||
* processing job for you during rendering).*/
|
||||
typedef struct XMLDLLENTRY ToXMLStringTool
|
||||
{
|
||||
public:
|
||||
ToXMLStringTool(): buf(NULL),buflen(0){}
|
||||
~ToXMLStringTool();
|
||||
void freeBuffer();///<call this function when you have finished using this object to release memory used by the internal buffer.
|
||||
|
||||
XMLSTR toXML(XMLCSTR source);///< returns a pointer to an internal buffer that contains a XML-encoded string based on the "source" parameter.
|
||||
|
||||
/** The "toXMLUnSafe" function is deprecated because there is a possibility of
|
||||
* "destination-buffer-overflow". It converts the string
|
||||
* "source" to the string "dest". */
|
||||
static XMLSTR toXMLUnSafe(XMLSTR dest,XMLCSTR source); ///< deprecated: use "toXML" instead
|
||||
static int lengthXMLString(XMLCSTR source); ///< deprecated: use "toXML" instead
|
||||
|
||||
private:
|
||||
XMLSTR buf;
|
||||
int buflen;
|
||||
} ToXMLStringTool;
|
||||
/** @} */
|
||||
|
||||
/** @defgroup XMLParserBase64Tool Helper class to include binary data inside XML strings using "Base64 encoding".
|
||||
* @ingroup XMLParserGeneral
|
||||
* @{ */
|
||||
/// Helper class to include binary data inside XML strings using "Base64 encoding".
|
||||
/** The "XMLParserBase64Tool" class allows you to include any binary data (images, sounds,...)
|
||||
* into an XML document using "Base64 encoding". This class is completely
|
||||
* separated from the rest of the xmlParser library and can be removed without any problem.
|
||||
* To include some binary data into an XML file, you must convert the binary data into
|
||||
* standard text (using "encode"). To retrieve the original binary data from the
|
||||
* b64-encoded text included inside the XML file, use "decode". Alternatively, these
|
||||
* functions can also be used to "encrypt/decrypt" some critical data contained inside
|
||||
* the XML (it's not a strong encryption at all, but sometimes it can be useful). */
|
||||
typedef struct XMLDLLENTRY XMLParserBase64Tool
|
||||
{
|
||||
public:
|
||||
XMLParserBase64Tool(): buf(NULL),buflen(0){}
|
||||
~XMLParserBase64Tool();
|
||||
void freeBuffer();///< Call this function when you have finished using this object to release memory used by the internal buffer.
|
||||
|
||||
/**
|
||||
* @param formatted If "formatted"=true, some space will be reserved for a carriage-return every 72 chars. */
|
||||
static int encodeLength(int inBufLen, char formatted=0); ///< return the length of the base64 string that encodes a data buffer of size inBufLen bytes.
|
||||
|
||||
/**
|
||||
* The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
|
||||
* from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
|
||||
* The string will be free'd when the XMLParserBase64Tool object is deleted.
|
||||
* All returned strings are sharing the same memory space. */
|
||||
XMLSTR encode(unsigned char *inByteBuf, unsigned int inByteLen, char formatted=0); ///< returns a pointer to an internal buffer containing the base64 string containing the binary data encoded from "inByteBuf"
|
||||
|
||||
/// returns the number of bytes which will be decoded from "inString".
|
||||
static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);
|
||||
|
||||
/**
|
||||
* The "decode" function returns a pointer to a buffer containing the binary data decoded from "inString"
|
||||
* The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
|
||||
* All output buffer are sharing the same memory space.
|
||||
* @param inString If "instring" is malformed, NULL will be returned */
|
||||
unsigned char* decode(XMLCSTR inString, int *outByteLen=NULL, XMLError *xe=NULL); ///< returns a pointer to an internal buffer containing the binary data decoded from "inString"
|
||||
|
||||
/**
|
||||
* decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
|
||||
* in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
|
||||
* will be returned; otherwise "TRUE". */
|
||||
static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL); ///< deprecated.
|
||||
|
||||
private:
|
||||
void *buf;
|
||||
int buflen;
|
||||
void alloc(int newsize);
|
||||
}XMLParserBase64Tool;
|
||||
/** @} */
|
||||
|
||||
#undef XMLDLLENTRY
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user