Ideal architecture design for namespace parameters - c++

I have 3 header files
// a1.h
namespace a
{
enum abc:uint8
{
abc1 = 1
abc2 = 2
};
}
// a2.h
namespace b
{
enum abc:uint8
{
abc1 = 1
abc2 = 2
abc3 = 3
};
}
// out.h
namespace out
{
enum abc:uint8
{
abc1 = 1
abc2 = 2
abc3 = 3
};
}
I want to apply some operation dosomething(a::abc, &out::abc) or dosomething(b::abc, &out::abc) on the enum where I simply map input from (a::abc or b::abc) to output (out::abc) using switch statements. The easiest solution would be to write two separate functions for different namespaces.
I am wondering if the dosomething function can be templatized given that
Enum values are same (number of enum values are same e.g all have abc1, abc2)
Enum values are different (namespace b::abc::abc1 = 3, b::abc::abc2 = 4)
New enum value introduced (eg. b::abc::abc3)
This would avoid code duplication and make the design extendable.
I have constraint that I cannot modify header files.

It is quite doable with a static_cast, you don't need a separate function at all:
a::abc A = a::abc2;
b::abc B = b::abc3;
a::abc A2 = static_cast<a::abc>(B);
cout << A << " " << A2 << " " << B;
Outputs 2 3 3 as expected.
https://www.ideone.com/pKltlP

Related

How to transfer constraints of string type to z3 solver expr in C++?

For example, I got a constraint: "(number < 10) && (name == "hello")";
I can do the following now:
context c;
expr number= c.int_const(number);
expr name = c->string_val(name.c_str());
expr constrain = ***procedure***("(number < 10) && (name == \"hello\")");
How can I implement this procedure()?
there is an incomplete and unproofed answer in Use a C++ string in z3::expr?, and I still can not figure out how to implement it?
I am very eagered and appreciateed for your help! Thanks!
Try:
#include <z3++.h>
using namespace z3;
using namespace std;
int main ()
{
context c;
expr number = c.int_const("number");
expr name = c.constant(c.str_symbol("name"), c.string_sort());
expr hello = c.string_val("hello");
expr constraint = number < 10 && name == hello;
solver s(c);
s.add(constraint);
cout << s.check() << "\n";
cout << s.get_model() << "\n";
return 0;
};
Assuming you put the above in a file called a.cpp, you compile it like this:
$ g++ -std=c++11 a.cpp -l z3
And when run, it produces:
sat
(define-fun number () Int
9)
(define-fun name () String
"hello")
Using higher-level APIs
As you no doubt noticed, programming z3 in C/C++ is very verbose and terribly error prone. Unless you've some other reason to use C/C++, I'd recommend using a higher-level API, such as Python or Haskell, which simplifies programming in z3 to a great extent.
Python
For instance, you'd code your problem in Python like this:
from z3 import *
number = Int('number')
name = String('name')
s = Solver()
s.add(number < 10, name == "hello")
print(s.check())
print(s.model())
producing:
sat
[number = 9, name = "hello"]
Haskell
And in Haskell, it would look like:
import Data.SBV
ex :: IO SatResult
ex = sat $ do number <- sInteger "number"
name <- sString "name"
constrain $ number .< 10 .&& name .== literal "hello"
producing:
*Main> ex
Satisfiable. Model:
number = 9 :: Integer
name = "hello" :: String
Summary
Long story short, programming z3 in C/C++—while entirely possible—is something that's best avoided if you can use a higher-level interface. If you must stick to C/C++, be sure to study the API: https://z3prover.github.io/api/html/namespacez3.html

CVC4: using quantifiers in C++ interface

I am trying to figure out how to code quantifiers in CVC4, using the C++ interface. Here is an example I am trying to get to run, but cannot.
int main() {
SmtEngine smt(&em);
smt.setLogic("AUFLIRA"); // Set the logic
Expr three = em.mkConst(Rational(3));
Expr four = em.mkConst(Rational(4));
// make the list of bound variables in CVC4
Expr bound_var = em.mkBoundVar("x_bound", em.integerType());
vector<Expr> bound_vars;
bound_vars.push_back(bound_var);
Expr bound_var_list = em.mkExpr(kind::BOUND_VAR_LIST, bound_vars);
Expr declare = em.mkExpr(kind::EQUAL, bound_var, three); //x_bound =3
Expr check = em.mkExpr(kind::EQUAL, bound_var, four); //x_bound=4
//forall x_bound, x_bound=3, the constraint I want to declare as true
Expr expr = em.mkExpr(kind::FORALL, bound_var_list, declare);
smt.assertFormula(expr);
smt.push();
// expect to be INVALID
// I want to check that given forall x_bound, x_bound = 3
// then I ask CVC4: is it true that x_bound=4, or is it false?
std::cout << "Quantifier " << smt.query(check) << std::endl;
return 0;
}
Instead, I just get an error message:
Bound variables test
Quantifier unknown (INCOMPLETE)
But I define the quantifier as forall. What did I do wrong?
EDIT (asked https://www.andrew.cmu.edu/user/liminjia/):
Syntax is wrong. We want to know if
(forall x, x=3) IMPLIES (forall x, x=4)
is true or not. But CVC4 does not if the above formula is valid or not, because SMT solvers are not full-fledged first-order logic theorem provers.
If you want to try something that works, try in CVC4 language:
QUERY (FORALL (x:INT): x =4);
And in C++, we have
// check that forall x, x=3 is INVALID
void cvc4BoundVar() {
std::cout << "Bound variables test" << std::endl;
SmtEngine smt(&em);
smt.setLogic("AUFLIRA"); // Set the logic
Expr three = em.mkConst(Rational(3));
Expr v_expr = em.mkBoundVar("x_bound", em.integerType());
vector<Expr> bound_vars;
bound_vars.push_back(v_expr);
Expr bound_var_list = em.mkExpr(kind::BOUND_VAR_LIST, bound_vars);
Expr declare = em.mkExpr(kind::EQUAL, v_expr, three); //x=3
Expr check = em.mkExpr(kind::EQUAL, v_expr, three);
Expr expr = em.mkExpr(kind::FORALL, bound_var_list, declare); //forall x, x=3
std::cout << "Quantifier " << smt.query(expr) << std::endl;
}

validate integer is some enum class item (C++11)

i have some enum class
enum class Foo { A=1, B=18 , Z=42 };
i want to check if some integer can be converted into a Foo.
What would be the ideal way to do this? this is for runtime check (the integer is not known yet at compile-time)
Obviously i can do this the hard way (write a function bool CheckEnum(Foo); with a big-ass switch returning true for all cases except the default one), but i was hoping a more elegant mechanism that avoided so much writing. MPL or Boost.Preprocessor would be a perfectly acceptable solution, but one of which i sadly know very little about
A solution to this problem is to ditch the enums, and replace it with some arrays which are created using XMACROs.
There is no "ideal" way to do it. All ways are going to have to involve some manual work.
You need to create a data structure that contains all of the acceptable values. Then search that data structure with the runtime value you need. A std::set or std::unordered_set would be adequate for this purpose.
Your main difficulty will be in maintaining that list, as it will need to be updated every time you change your enum class.
Ok i'm a little bit fed up with this issue (some of my enums are nearly 100 items)
so i decided to tackle it with code generation, which might not be everyone's cup of tea, but i've realised that is really no such a big deal.
Basically i went for Python Cog, which allows me to embed python snippets inside comments in my .h and .cpp files and auto-generate code. I use it basically like a really smart, imperative macro system:
i added the following to Test.h
/*[[[cog
#----------- definitions
import cog
def createCategoryConstants( enumVar , bitShift ):
categoryIndex = 0
for cat in enumVar:
cog.outl(' const unsigned int %s_op_mask = (%d << %d); ' %(cat[0] , categoryIndex , bitShift))
categoryIndex += 1
cog.outl('\n\n')
def createMultiCategoryEnum( enumVar , enumTypename ):
cog.outl(' enum class %s { ' % enumTypename )
categoryIndex = 0
for i in enumVar:
itemIndex = 0
catName = 'NotExpected'
remainingCategories = len(enumVar)- categoryIndex - 1
for j in i:
if (itemIndex == 0):
catName = j
itemIndex = 1
continue
enumItemIndex = 0
for enumItem in j:
remainingEnums = len(j) - enumItemIndex - 1
currentLine = ' %s = %s_op_mask | %d ' %(enumItem, catName, enumItemIndex)
if (remainingCategories != 0 or remainingEnums != 0):
currentLine += ' , '
cog.outl(currentLine)
enumItemIndex += 1
itemIndex += 1
cog.outl('') #empty line to separate categories
categoryIndex += 1
cog.outl(' };\n\n')
def createIndexFromEnumFunction( enumVar , enumTypename , functionName ):
cog.outl('uint32_t %s(%s a) { \n switch (a)\n {' % (functionName , enumTypename) )
absoluteIndex = 0
for cat in enumVar:
elemInCat = 0
for i in cat:
if elemInCat != 0:
for enumItem in i:
cog.outl('case %s:' % enumItem)
cog.outl(' return %d; \n' % absoluteIndex)
absoluteIndex += 1
elemInCat += 1
cog.outl(' } \n } \n\n ')
def createMultiEnum( enumVar , enumTypename ):
createCategoryConstants( enumVar , 4)
createMultiCategoryEnum( enumVar , enumTypename )
createIndexFromEnumFunction( enumVar , enumTypename , 'FromOpToIndex' )
#------------- generation
multiEnum =[ ['CatA', ['A1', 'A2' , 'A3_foo']] , ['CatSuper8' , ['Z1_bla' , 'Z10' , 'Z11']] ]
createMultiEnum( multiEnum , 'multiFooEnum')
]]]*/
//[[[end]]]
Then i added cog invocation in my Makefile pre-build step:
.build-pre:
# Add your pre 'build' code here...
python /usr/local/bin/cog.py -I../../../tools/cog/ -r *.h
And the results show up just below:
]]]*/
const unsigned int CatA_op_mask = (0 << 4);
const unsigned int CatSuper8_op_mask = (1 << 4);
enum class multiFooEnum {
A1 = CatA_op_mask | 0 ,
A2 = CatA_op_mask | 1 ,
A3_foo = CatA_op_mask | 2 ,
Z1_bla = CatSuper8_op_mask | 0 ,
Z10 = CatSuper8_op_mask | 1 ,
Z11 = CatSuper8_op_mask | 2
};
uint32_t FromOpToIndex(multiFooEnum a) {
switch (a)
{
case A1:
return 0;
case A2:
return 1;
case A3_foo:
return 2;
case Z1_bla:
return 3;
case Z10:
return 4;
case Z11:
return 5;
}
}
//[[[end]]]
So, now my enum validation is about making sure the code generation (invoked at compile time) is done correctly

Returning list in ANTLR for type checking, language java

I am working on ANLTR to support type checking. I am in trouble at some point. I will try to explain it with an example grammar, suppose that I have the following:
#members {
private java.util.HashMap<String, String> mapping = new java.util.HashMap<String, String>();
}
var_dec
: type_specifiers d=dec_list? SEMICOLON
{
mapping.put($d.ids.get(0).toString(), $type_specifiers.type_name);
System.out.println("identext = " + $d.ids.get(0).toString() + " - " + $type_specifiers.type_name);
};
type_specifiers returns [String type_name]
: 'int' { $type_name = "int";}
| 'float' {$type_name = "float"; }
;
dec_list returns [List ids]
: ( a += ID brackets*) (COMMA ( a += ID brackets* ) )*
{$ids = $a;}
;
brackets : LBRACKET (ICONST | ID) RBRACKET;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
LBRACKET : '[';
RBRACKET : ']';
In rule dec_list, you will see that I am returning List with ids. However, in var_dec when I try to put the first element of the list (I am using only get(0) just to see the return value from dec_list rule, I can iterate it later, that's not my point) into mapping I get a whole string like
[#4,6:6='a',<17>,1:6]
for an input
int a, b;
What I am trying to do is to get text of each ID, in this case a and b in the list of index 0 and 1, respectively.
Does anyone have any idea?
The += operator creates a List of Tokens, not just the text these Tokens match. You'll need to initialize the List in the #init{...} block of the rule and add the inner-text of the tokens yourself.
Also, you don't need to do this:
type_specifiers returns [String type_name]
: 'int' { $type_name = "int";}
| ...
;
simply access type_specifiers's text attribute from the rule you use it in and remove the returns statement, like this:
var_dec
: t=type_specifiers ... {System.out.println($t.text);}
;
type_specifiers
: 'int'
| ...
;
Try something like this:
grammar T;
var_dec
: type dec_list? ';'
{
System.out.println("type = " + $type.text);
System.out.println("ids = " + $dec_list.ids);
}
;
type
: Int
| Float
;
dec_list returns [List ids]
#init{$ids = new ArrayList();}
: a=ID {$ids.add($a.text);} (',' b=ID {$ids.add($b.text);})*
;
Int : 'int';
Float : 'float';
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
Space : ' ' {skip();};
which will print the following to the console:
type = int
ids = [a, b, foo]
If you run the following class:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
TLexer lexer = new TLexer(new ANTLRStringStream("int a, b, foo;"));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.var_dec();
}
}

How can you simulate a SQL join in C++ using STL and or Boost

How can you simulate a SQL join between two dynamic data sets ( i.e. data is obtained at runtime ) using c++.
Example Table A is a 2D vector of vectors ( any STL or Boost data structure is OK ) of students, their names and course numbers. Table B is a 2D vector of vectors ( any STL or Boost data structure is ok) of course number, description and room numbers
//Table A
// Columns: StudentID FirstName LastName CourseNum
std::vector<std::string> a1 = boost::assign::list_of("3490")( "Saundra")( "Bribiesca")( "F100X");
std::vector<std::string> a2 = boost::assign::list_of("1288")( "Guy")( "Shippy")( "F103X");
std::vector<std::string> a3 = boost::assign::list_of("5383")( "Tia")( "Roache")( "F103X");
std::vector<std::string> a4 = boost::assign::list_of("5746")( "Jamie")( "Grunden")( "F101X");
std::vector<std::string> a5 = boost::assign::list_of("2341")( "Emilia")( "Hankinson")( "F120X");
std::vector<std::vector<std::string > > TableA = boost::assign::list_of(a1)(a2)(a3)(a4)(a5);
//Table B
//Columns: CourseNum CourseDesc Room
std::vector<std::string> b1 = boost::assign::list_of("F100X")("Human Biology")("400B");
std::vector<std::string> b2 = boost::assign::list_of("F103X")("Biology and Society")("500B");
std::vector<std::string> b3 = boost::assign::list_of("F101X")("The Dynamic Earth 340A");
std::vector<std::string> b4 = boost::assign::list_of("F120X")("Glaciers, Earthquakes and Volcanoes")("300C");Earthquakes and Volcanoes");
std::vector<std::vector<std::string > > TableB = boost::assign::list_of(b1)(b2)(b3)(b4);
//Table C ( result of joining A and B ) using TableA[3] and TableB[0] as key
//I want to produce a resultset Table C, like this
Table C
StudentID FirstName LastName Room CourseNum CourseDesc
3490 Saundra Bribiesca 400B F100X Human Biology
1288 Guy Shippy 500B F103X Biology and Society
5383 Tia Roache 500B F103X Biology and Society
5746 Jamie Grunden 340A F101X The Dynamic Earth
2341 Emilia Hankinson 300C F120X Glaciers, Earthquakes and Volcanoes
SQL engines use various different techniques to perform joins, depending what indexes are available (or what hashtables it thinks should be created on the fly).
The simplest though is an O(N*M) nested loop over both tables. So to do an inner join you compare every pair of elements one from A and one from B. When you see a match, output a row.
If you need to speed things up, in this case you could create an "index" of table B on its first column, that is a std::multimap with the first column as the key, and a tuple[*] of the rest of the columns as value. Then for each row in A, look up its third column in the index and output one row per match. If the CourseNum is unique in table B, as seems sensible, then you can use a map rather than a multimap.
Either way gets you from O(N*M) to O((N+M)*logM), which is an improvement unless N (the size of table A) is very small. If your college has very many fewer students than courses, something is badly wrong ;-)
[*] where by "tuple" I mean anything that holds all the values - you've been using vectors, and that will do.
Since only answer doesn't have any code...
Please note that design (vector of strings instead of class makes code unreadable)
int main()
{
map<string,std::vector<vector<string > >::const_iterator> mapB;
for(auto it = TableB.cbegin(); it!=TableB.cend(); ++it)
{
mapB[(*it)[0]]=it;// in first map we put primary key and iterator to tableB where that key is
}
assert(mapB.size()== TableB.size());// how unique is primary key?
for_each(TableA.cbegin(), TableA.cend(),
[&mapB] (const vector<string>& entryA )
{
auto itB= mapB.find(entryA.at(3));
if (itB!=mapB.end()) // if we can make "JOIN" we do it
{
auto entryB = itB->second;
cout << entryA.at(0) << " " << entryA.at(1) << " " << entryA.at(2) << " " << entryB->at(2) << " " << entryB->at(0) << " " << entryB->at(1) << endl;
}
});
}
Output:
C:\STL\MinGW>g++ test.cpp &&a.exe
3490 Saundra Bribiesca 400B F100X Human Biology
1288 Guy Shippy 500B F103X Biology and Society
5383 Tia Roache 500B F103X Biology and Society
5746 Jamie Grunden 340A F101X The Dynamic Earth
2341 Emilia Hankinson 300C F120X Glaciers, Earthquakes and Volcanoes