I want to transform an expression into negation normal form. For this, I have a binary expression tree using smart pointers. The problem is that removing double negations is not working when they occur in binary expressions although the function removeDoubleNot() is called at the right time. So e.g. ¬(A∨¬B) becomes ¬A∧¬¬B instead of ¬A∧B, but it works on ¬¬B alone. I assume the mistake is in evaluate() but I could not find it yet. Maybe the recursion is wrong?
// It is assumed that all Expressions are valid
std::shared_ptr<Expression> NNF::removeDoubleNot(std::shared_ptr<Not> expr) {
// Left is a Not -> remove both Nots
if (auto node = dynamic_cast<Not *>(expr->getLeft().get()))
return node->getLeft();
return expr;
}
std::shared_ptr<Expression> NNF::applyDeMorgan(std::shared_ptr<Not> expr) {
// And
if (auto node = dynamic_cast<And *>(expr->getLeft().get())) {
auto newLeft = std::make_shared<Not>(node->getLeft());
auto newRight = std::make_shared<Not>(node->getRight());
return std::make_shared<Or>(newLeft, newRight);
}
// Or
if (auto node = dynamic_cast<Or *>(expr->getLeft().get())) {
auto newLeft = std::make_shared<Not>(node->getLeft());
auto newRight = std::make_shared<Not>(node->getRight());
return std::make_shared<And>(newLeft, newRight);
}
return expr;
}
std::shared_ptr<Expression> NNF::removeImplication(const std::shared_ptr<Implication> &expr) {
auto newLeft = std::make_shared<Not>(expr->getLeft());
auto newRight = expr->getRight();
return std::make_shared<Or>(newLeft, newRight);
}
std::shared_ptr<Expression> NNF::moveNegationInwards(const std::shared_ptr<Not> ¬Expr) {
expr = applyDeMorgan(node);
if (auto node = std::dynamic_pointer_cast<Not>(expr))
expr = removeDoubleNot(node);
return expr;
}
std::shared_ptr<Expression> NNF::evaluate(std::shared_ptr<Expression> expr) {
if (expr == nullptr)
return nullptr;
// Implication
if(auto node = std::dynamic_pointer_cast<Implication>(expr)){
auto ret = removeImplication(node);
evaluate(ret->getLeft());
evaluate(ret->getRight());
return ret;
}
// Other binary than implication
if(auto node = dynamic_cast<Binary*>(expr.get())){
evaluate(node->getLeft());
evaluate(node->getRight());
return expr;
}
// Not
if(auto node = std::dynamic_pointer_cast<Not>(expr)) {
auto ret = moveNegationInwards(node);
evaluate(ret->getLeft());
evaluate(ret->getRight());
return ret;
}
return expr;
}
When you call evaluate(ret->getLeft()) you are not using the return value, thus you never change your current child expressions.
So you need to change this to:
ret->setLeft(evaluate(ret->getLeft()));
The same goes for right.
You might want to consider using [[nodiscard]] to get compiler warnings on mistakes like these.
Related
I am working on a project base on LLVM 7.0.0, I transfer the llvm version form 3.5 to 7.0.0, I have build the project and is ok, but when I running llc on a .bc file, here is the bug confused me, I have find everything on the Internet and no solution, here is the stack dump message:
llc: llvm/include/llvm/Support/Casting.h:106: static bool llvm::isa_impl_cl<To, const From*>::doit(const From*) [with To = llvm::StructType; From = llvm::CompositeType]: Assertion `Val && "isa<> used on a null pointer"' failed.
Bug in code here:
int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
ArrayRef<Value *> Indices) const {
int64_t Result = 0;
generic_gep_type_iterator<Value* const*>
GTI = gep_type_begin(ElemTy, Indices),
GTE = gep_type_end(ElemTy, Indices);
for (; GTI != GTE; ++GTI) { // stack dump here when ++GTI
Value *Idx = GTI.getOperand();
if (StructType *STy = GTI.getStructTypeOrNull()) {
assert(Idx->getType()->isIntegerTy(32) && "Illegal struct idx");
unsigned FieldNo = cast<ConstantInt>(Idx)->getZExtValue();
// Get structure layout information...
const StructLayout *Layout = getStructLayout(STy);
// Add in the offset, as calculated by the structure layout info...
Result += Layout->getElementOffset(FieldNo);
} else {
// Get the array index and the size of each array element.
if (int64_t arrayIdx = cast<ConstantInt>(Idx)->getSExtValue())
Result += arrayIdx * getTypeAllocSize(GTI.getIndexedType());
}
}
return Result;
}
generic_gep_type_iterator& operator++() { // Preincrement
Type *Ty = getIndexedType(); // program is stack dump here.
if (auto *STy = dyn_cast<SequentialType>(Ty)) {
CurTy = STy->getElementType();
NumElements = STy->getNumElements();
} else
CurTy = dyn_cast<StructType>(Ty);
++OpIt;
return *this;
}
template <class X, class Y>
LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
return isa<X>(Val) ? cast<X>(Val) : nullptr; //stack dump here
}
Then when I debug the program, I find this message:
llvm/include/llvm/IR/GetElementPtrTypeIterator.h:
// FIXME: Make this the iterator's operator*() after the 4.0 release.
// operator*() had a different meaning in earlier releases, so we're
// temporarily not giving this iterator an operator*() to avoid a subtle
// semantics break.
Type *getIndexedType() const {
if (auto *T = CurTy.dyn_cast<Type *>())
return T;
return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
}
Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
generic_gep_type_iterator &operator++() { // Preincrement
Type *Ty = getIndexedType();
if (auto *ATy = dyn_cast<ArrayType>(Ty))
CurTy = ATy->getElementType();
else if (auto *VTy = dyn_cast<VectorType>(Ty))
CurTy = VTy->getElementType();
else
CurTy = dyn_cast<StructType>(Ty);
++OpIt;
return *this;
}
generic_gep_type_iterator operator++(int) { // Postincrement
generic_gep_type_iterator tmp = *this;
++*this;
return tmp;
}
That "// FIXME: Make this the iterator's operator*() after the 4.0 release.", I am confused about what is that message want let me do, there is anything I need to add or fix at that position, so that helpful to fix the Stack dump.
Any suggestions will be be appreciated, thanks a lot!
You are having:
if (auto *STy = dyn_cast<SequentialType>(Ty)) {
CurTy = STy->getElementType();
NumElements = STy->getNumElements();
} else
CurTy = dyn_cast<StructType>(Ty);
so, if dyn_cast fails, then CurTy might be nullptr and on next getIndexedType() you'll obtain the assertion. Likely you're passing neither SequentialType nor StructType here.
I have a vector or list of which I only want to apply code to specific elements. E.g.
class Container : public std::vector<Element*>
Or
class Container : public std::list<Element*>
And:
Container newContainer = inputContainer.Get(IsSomething);
if (!newContainer.empty()) {
for (Element* const el: newContainer ) {
[some stuff]
}
} else {
for (Element* const el : inputContainer) {
[some stuff]
}
}
I've written a member function Get() as follows.
template<typename Fn>
auto Container::Get(const Fn& fn) const {
Container output;
std::copy_if(cbegin(), cend(), std::inserter(output, output.end()), fn);
return output;
}
and IsSomething would be a lambda, e.g.
auto IsSomething= [](Element const* const el)->bool { return el->someBool; };
From performance perspective: Is this a good approach? Or would it be better to copy and remove?
template<typename Fn>
auto Container::Get(const Fn& fn) const {
Container output(*this);
output.erase(std::remove_if(output.begin(), output.end(), fn), end(output));
return output;
}
Or is there a better approach anyhow?
edit: different example
As my previous example can be written in a better way, let's show a different example:
while (!(container2 = container1.Get(IsSomething)).empty()&&TimesFooCalled<SomeValue)
{
Container container3(container2.Get(IsSomething));
if (!container3.empty()) {
Foo(*container3.BestElement());
} else {
Foo(*container2.BestElement());
}
}
Not answering your direct question, but note that you can implement the original algorithm without copying anything. Something like this:
bool found = false;
for (Element* const el: inputContainer) {
if (IsSomething(el)) {
found = true;
[some stuff]
}
}
if (!found) {
for (Element* const el : inputContainer) {
[some stuff]
}
}
The usual pattern that I use is something like this:
for(auto const * item : inputContainer) if(IsSomething(item)) {
// Do stuff with item
}
This is usually good enough, so other approaches seem overkill.
For better performance it is always better not to copy or remove elements from the list you get. In my experience it's even faster if you only go through the list once, for caching reasons. So here is what I would do to find one or the other "best" value from a list:
auto const isBetter = std::greater<Element>();
Element const * best = nullptr, const * alt_best = nullptr;
for(Element const * current : inputContainer) {
if(IsSomething(current)) {
if(!best || isBetter(*best, *current)) best = current;
} else {
if(!alt_best || isBetter(*alt_best, *current)) alt_best = current;
}
}
if(best) {
// do something with best
} else if(alt_best) {
// do something with alt_best
} else {
// empty list
}
If you find yourself doing this a lot or you want to make this part of your class's interface you could consider writing an iterator that skips elements you don't like.
If you actually want to remove the item from the list, you could do something like this:
inputContainer.erase(std::remove_if(std::begin(inputContainer), std::end(inputContainer),
[](Element const *item) {
if(IsSomething(item)) {
// Do something with item
return true;
}
return false;
}
));
I wanted to find how to use find_if to find the SceneNode based on ID. I am unsure how to do this though.
I was able to for example, do this to remove the SceneNode based on the actual pointer like so:
SceneNode::Ptr SceneNode::detachChild(const SceneNode& node)
{
auto found = std::find_if(mChildren.begin(), mChildren.end(), [&](Ptr& p) -> bool {return p.get() == &node; });
...
but I am unsure on how to deal with find_if if I am looking for SceneNodes mID variable (which is an INT).
I.E.
SceneNode::Ptr SceneNode::findChild(int findID)
{
auto found = std::find_if(mChildren.begin(), mChildren.end(), ... ? = findID?; });
...
Does anyone have any good sites or info for me that explains find_if well? Thanks!
You basically had it...
auto found = std::find_if(
mChildren.begin(),
mChildren.end(),
[&](Ptr& p) -> bool { return p->mID == node.mID; }
);
Based on your first example, it appears that a Ptr & is the result of mChildren.begin().operator*() (or something compatible).
So:
SceneNode::Ptr SceneNode::findChild(int findID)
{
auto found = std::find_if(
mChildren.begin(), mChildren.end(),
[findID](Ptr &ptr)
{
return findID == ptr.get()->mID;
});
...
}
I think you want something like this:
SceneNode::Ptr SceneNode::findChild(int findID)
{
auto found = std::find_if(std::begin(mChildren), std::end(m_children),
[=](Ptr& p) { return p->mID == findID; }
);
// ...
}
This lambda will capture findID by value and compare it with the mID member of what Ptr points to.
For example I have an vector of objects and they all have attribute PointX so I want to check if all of them have the same value of PointX and if they have it should return true or false whatever.
So in a kind of pseudo-code:
IF ( Object[1].getPointX() == Object[2].getPoint(x) == Object[3].getPoint(x) ){
return true;
}
The problem is that I have more than 55 objects so there has to be a way to compare them without writting them all individually. I know there must be with a for loop but still I have no idea.
thanks in advance.
edit:
#awesomeyi your suggestion seems the easiest and more adequate to my needs (I'm not saying the others are not but I think they are too complicated for a newb like me) but it's not working, even if Xpoints are all the same or different it always returns false. here's what i have:
bool allKilled(){
auto checkpointx = Invader[0].getIfActive();
for(int i = 0; i < 55; ++i){
if(Invader[i].getIfActive() != checkpointx){
return false;}
}
}
the getIfActive() just returns if its true or false, and i want this method to return true if all Active (attribute of the object) of all objects are all false.
Something like this:
auto refx = Object[0].getPointX();
bool b = std::all_of(Object.begin(),
Object.end(),
[refx](TheTypeOfTHeElements& e)
{ return e.getPointX() == ref; });
Obviously you need to check that Objects is not empty.
For loop?
auto checkpointx = Object[0].getPointX();
for(int i = 1; i < Object.size(); ++i){
if(Object[i].getPointX() != checkpointx)
return false;
}
I'd do it something like this:
template<typename Objects, typename Comparison>
bool is_all_same( Objects&& objects, Comparison&& comp ) {
using std::begin; using std::end;
auto&& b = begin(objects);
auto&& e = end(objects);
if (b == e)
return true;
auto&& first = *b;
for( auto&& cur = std::next(first); cur != e; ++cur ) {
if (!comp( first, cur ))
return false;
}
return true;
}
use:
bool all_same_x = is_all_same( objs, []( Obj const& left, Obj const& right )->bool {
return left.getPointX() == right.getPointX();
});
where objs is some container or range containing objects of type Obj.
The above code should work on all standard containers, C style arrays, custom containers that support the new for loops, and is close to optimal performance wise.
Previous investigation in Can I make a table of String + lambdas that have the same signature? showed me that I can in fact have a table of strings + lambdas in VS2010.
Things were looking good while the lambdas were void return type. But having tried to change them to bool return type, the compiler seems to get it wrong, or there's some sort of a memory corruption error... something's not right in C++ land...
The following illustrates the scenario:
// fun: use a table of lambdas to define what to do in order to update each field
typedef std::function<bool (CDynamicMenuItem *, ITEM *)> LambdaType;
struct UpdateField {
const TCHAR * label;
LambdaType lambda; // this version allows us to use captures in our lambdas, whereas the following doesn't
//void (*lambda)(CDynamicMenuItem *, ITEM *); // this would work in VS11, but the conversion of lambda to function pointer was defined after 2010's release!
};
UpdateField MenuFields[] = {
{ "Identity", [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { return pMenuItem->SetText(FString("%s/%.1f", pNearestItem->thissec->name, pNearestItem->number/10.0)), true; } },
{ "X1", [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { double v = GetX1(pNearestItem); return (v != v) ? false : pMenuItem->SetValue(v), true; } },
{ "Y1", [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { double v = GetY1(pNearestItem); if (v != v) return false; pMenuItem->SetValue(v); return true; } },
{ "X2", [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { double v = GetX2(pNearestItem); if (v != v) return false; pMenuItem->SetValue(v); return true; } },
{ "Y2", [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { double v = GetY2(pNearestItem); if (v != v) return false; pMenuItem->SetValue(v); return true; } },
{ "Xd", [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { double v = GetXd(pNearestItem); if (v != v) return false; pMenuItem->SetValue(v); return true; } },
{ "Yd", [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { double v = GetYd(pNearestItem); if (v != v) return false; pMenuItem->SetValue(v); return true; } },
{ "Angle", [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { double v = GetAngle(pNearestItem); if (v != v) return false; pMenuItem->SetValue(v); return true; } },
{ "Length", [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { double v = GetLength(pNearestItem); if (v != v) return false; pMenuItem->SetValue(v); return true; } },
};
for (UpdateField * it = &MenuFields[0], * end = (MenuFields + countof(MenuFields)); it != end; ++it)
{
CDynamicMenuItem * pMenuItem = pMenu->FindItem(it->label);
if (pMenuItem)
{
if (!m_pNearestItem || !it->lambda(pMenuItem, m_pNearestItem))
pMenuItem->SetText("");
}
}
The above worked beautifully when the lambda's return type is void (i.e. ->bool is omitted, and the various lambda bodies are modified to not return anything, etc.).
However, it's useful to me to have them return a bool indicating whether or not the lambda was able to process data for that field, and if not, to have the caller handle clearing that field.
To be certain, the code compiles & runs... until it hits this code & CRASHES. Looking at "MenuFields[]" in the debugger shows garbage for most of the MenuField[x].label addresses (sometimes one of them is correct, but I haven't figured out what the pattern is).
I thought maybe the compiler was glitching over the syntax of the lambda embedded in the static initialization list, but I'm not sure what I can do about that?
I tried this variation:
{ "Identity", LambdaType( [] (CDynamicMenuItem * pMenuItem, ITEM * pNearestItem) ->bool { return pMenuItem->SetText(FString("%s/%.1f", pNearestItem->thissec->name, pNearestItem->number/10.0)), true; } ) },
The compiler likes this equally well, but it results in the same corrupted table data.
Similarly, putting parenthesis around the entire lambda is okay by the compiler, and equally corrupt at runtime.
So, some questions:
Do you see something I overlooked?
Can you think of a work around to get the compiler to generate the correct code (other than going back to void return - which is plausible for my scenario, and my likely next step barring a better suggestion)?
Know how best to report this to Microsoft? [I have had no luck finding actual human beings on the other end to give this sort of detailed info to so that it actually goes somewhere other than >nul)
This is indeed a bug in the Visual C++ compiler. See the bug report "miscompilation of aggregate initializer with lambdas inside".
As a workaround, consider not using the aggregate initialization here. Instead, you could use a std::vector:
UpdateField MakeUpdateField(char const* label, LambdaType const lambda)
{
UpdateField f = { label, lambda };
return f;
}
std::vector<UpdateField> fields = ([]() -> std::vector<UpdateField>
{
std::vector<UpdateField> data;
data.push_back(MakeUpdateField("Identity", [] { /* contents omitted */ }));
data.push_back(MakeUpdateField("X1", [] { /* contents omitted */ }));
data.push_back(MakeUpdateField("Y1", [] { /* contents omitted */ }));
return data;
})();
(If your data is a mapping of names to lambdas, you might also consider using a std::map, which might provide better performance characteristics or might be easier to use.)