Hello, we’re in the fifth session of expert system course, and now, we’re gonna implement a new class called PROPTreeBuilder. The principal objective of the PROPTreeBuilder is create and connect nodes between them building up the semantic tree skeleton.

Now, we created another class called PROPTreeBuilder, and we should begin with the PROPTreeBuilder declaration. The first step is to add header we’re gonna use. This headers are definition of STL-similar Qt containers (if you have any doubts about container, you may ask in the comments):


#include
#include
#include
#include "propnode.h"

Our private data members are totally containers, one representing the tree, one storing the symbols of every literal node, and two associative containers that hold the relationship between symbol and entry (Node’s position within tree).


QList m_lstTree;
QList m_lstSymbol;
QMap<QString,int> m_mapSymbol2Entry;
QMap<int,QString> m_mapEntry2Symbol;

Now, we’re gonna define functions that allow us to create a new node and add it to the tree. Also, there are access function that return copy of the associative containers.


PROPTreeBuilder()=default;
size_t atom(QString string);
size_t Not(int first);
size_t If(int first,int second);
size_t And(int first, int second);
size_t Iff(int first,int second);
size_t Or(int first, int second);
size_t True();
int valueAtomBySymbol(QString symbol);
QMap<QString,int> getMapSymbolEntry(){return this->m_mapSymbol2Entry;}
QMap<int,QString> getMapEntrySymbol(){return this->m_mapEntry2Symbol;}
QList getTree()const{return this->m_lstTree;}
QList getSymbols()const{return this->m_lstSymbol;}

The only responsability of the PROPTreeBuilder constructor is to clear the principal containers- the tree and symbols handler.

PROPTreeBuilder::PROPTreeBuilder()
{
m_lstTree.clear();
m_lstSymbol.clear();
}

The atom() function creates literal atom node (no operation), and attaches it to the tree. If the specific atom is already into the tree, avoid creating a copy. Whether it creates a new or not, returns the node’s position in the tree.


size_t PROPTreeBuilder::atom(QString strId){
auto it=m_mapSymbol2Entry.find(strId);
if(it != m_mapSymbol2Entry.cend())
return it.value();
else{
m_mapSymbol2Entry.insert(strId,m_lstTree.size());
m_mapEntry2Symbol.insert(m_lstTree.size(),strId);
m_lstTree.push_back(PROPNode(PROPNode::ATOM,m_lstSymbol.size(),-1));
m_lstSymbol.push_back(strId);
return m_lstTree.size()-1;
}
}

The other operation functions are similar than atom()  function, creates a specific node (based in the operation) and returns its position in the tree:


size_t PROPTreeBuilder::Not(int first){
m_lstTree.push_back(PROPNode(PROPNode::NOT,first,-1));
return m_lstTree.size()-1;
}
size_t PROPTreeBuilder::And(int first, int second){
m_lstTree.push_back(PROPNode(PROPNode::AND,first,second));
return m_lstTree.size()-1;
}
size_t PROPTreeBuilder::If(int first, int second){
m_lstTree.push_back(PROPNode(PROPNode::IF,first,second));
return m_lstTree.size()-1;
}
size_t PROPTreeBuilder::Iff(int first, int second){
m_lstTree.push_back(PROPNode(PROPNode::IFF,first,second));
return m_lstTree.size()-1;
}
size_t PROPTreeBuilder::Or(int first, int second){
m_lstTree.push_back(PROPNode(PROPNode::OR,first,second));
return m_lstTree.size()-1;
}
size_t PROPTreeBuilder::True(){
m_lstTree.push_back((PROPNode(PROPNode::TRUE,-1,-1)));
return m_lstTree.size()-1;
}

The last function in this article is called valueAtomBySymbol(). This function searches for the entry of a specific node by the symbol. For example, we can find where is A atom node in the tree using the character ‘A’ with this function.


int PROPTreeBuilder::valueAtomBySymbol(QString symbol){
if(m_mapSymbol2Entry.contains(symbol))
return m_mapSymbol2Entry.value(symbol);
return -1;
}

Everything we have discuss in this article are explained in the next video:

So, this articles is finished, remember: questions in the comment section, share if you like it, and visit the GearsTech’s social media.

Leave a Reply

Your email address will not be published.