bool KnowLedgeBasedAgent::askOr(string query, vector<string>& theta) { Predicate p = TextParser::GetPredicate(query); if (predicateMap.find(p.name) != predicateMap.end()) { vector<int>rules = predicateMap[p.name]; bool flag = false; for (int ruleIterator = 0; ruleIterator < rules.size(); ruleIterator++) { Sentence sentence = KnowledgeBase[rules[ruleIterator]-1]; vector<string> premise = sentence.GetPremise(); string conclusion = sentence.GetConclusion(); Predicate q = TextParser::GetPredicate(conclusion); string substitution = ""; bool unificationResult = Unify(p, q, substitution); if (!unificationResult) continue; if (find(theta.begin(), theta.end(), substitution) == theta.end()) { theta.push_back(*new string(substitution)); } bool validity = askAnd(premise, theta); if (validity) flag = true; else flag = false; } if(flag) return true; else return false; } else return false; }
ValuePtr BArithmetic<Operation>::Infer(TypeChecker& checker, const vector<ExprPtr>& args) { assert(args.size() == 2); auto& left = args[0]; auto& right = args[1]; checker.Visit(left.get()); if(!left->value) return {}; TypeSubst leftSubst; checker.subst.swap(leftSubst); checker.Visit(right.get()); if(!right->value) return {}; Compose(leftSubst, checker.subst); Compose(Unify(*left->value->type, *right->value->type), checker.subst); auto type = left->value->type.get(); if(!isa<TInteger>(type) && !isa<TFloat>(type)) { Error() << "Arithmetic operation requires float or integer operands"; return {}; } ValuePtr value = new VTemporary; value->type = ResultType<typename Operation::IsCompare>(type); return value; }
ValuePtr BWhile::Infer(TypeChecker& checker, const vector<ExprPtr>& args) { assert(args.size() == 2); auto& cond = args[0]; auto& body = args[1]; checker.Visit(cond.get()); if(!cond->value) return {}; TypeSubst condSubst; checker.subst.swap(condSubst); bool lastInsideLoop = checker.insideLoop; checker.insideLoop = true; checker.Visit(body.get()); checker.insideLoop = lastInsideLoop; if(!body->value) return {}; Compose(condSubst, checker.subst); Compose(Unify(*cond->value->type, *BooleanType), checker.subst); return VoidValue; // TODO should a while yield a value? }
ValuePtr BIf::Infer(TypeChecker& checker, const vector<ExprPtr>& args) { assert(args.size() >= 2 && args.size() % 2 == 0); // conditions for(size_t i = 0; i < args.size(); i += 2) { TypeSubst lastSubst; checker.subst.swap(lastSubst); checker.Visit(args[i].get()); if(!args[i]->value) return {}; Compose(lastSubst, checker.subst); Compose(Unify(*args[i]->value->type, *BooleanType), checker.subst); } // clauses for(size_t i = 1; i < args.size(); i += 2) { TypeSubst lastSubst; checker.subst.swap(lastSubst); checker.Visit(args[i].get()); if(!args[i]->value) return {}; Compose(lastSubst, checker.subst); if(i != 1) Compose(Unify(*args[i]->value->type, *args[i - 2]->value->type), checker.subst); } for(auto& e : args) e->value->type = xra::Apply(checker.subst, *e->value->type); if(args.size() == 2) return VoidValue; ValuePtr value = new VTemporary; value->type = args[1]->value->type; return value; }
ValuePtr BReturn::Infer(TypeChecker& checker, const vector<ExprPtr>& args) { assert(args.size() == 0 || args.size() == 1); TypePtr rty = VoidType; if(!args.empty()) { checker.Visit(args[0].get()); if(!args[0]->value) return {}; rty = args[0]->value->type; } if(checker.returnType) Compose(Unify(*rty, *checker.returnType), checker.subst); else checker.returnType = rty; return VoidValue; }
ValuePtr BAssign::Infer(TypeChecker& checker, const vector<ExprPtr>& args) { assert(args.size() == 2); auto& left = args[0]; auto& right = args[1]; checker.Visit(right.get()); if(!right->value) return {}; TypeSubst rightSubst; checker.subst.swap(rightSubst); // if the left side is a plain variable not in the environment, create a fresh local if(isa<EVariable>(left.get())) { auto& name = static_cast<EVariable&>(*left).name; if(!checker.env[name]) { left->value = new VLocal; left->value->type = MakeTypeVar(); checker.env.AddValue(name, left->value); } } if(!left->value) { checker.Visit(left.get()); if(!left->value) return {}; } Compose(rightSubst, checker.subst); auto unifySubst = Unify(*left->value->type, *right->value->type); left->value->type = xra::Apply(unifySubst, *left->value->type); Compose(unifySubst, checker.subst); return left->value; }
void wxDynamicSashWindowImpl::OnRelease(wxMouseEvent &event) { if ((m_dragging == DSR_CORNER) && (m_window->GetWindowStyle() & wxDS_DRAG_CORNER) != 0) { DrawSash(m_drag_x, m_drag_y); m_container->ReleaseMouse(); Resize(event.m_x, event.m_y); m_dragging = DSR_NONE; } else if (m_dragging) { DrawSash(m_drag_x, m_drag_y); m_container->ReleaseMouse(); wxSize size = m_container->GetSize(); int px = (int)((event.m_x * 100) / size.GetWidth() + 0.5); int py = (int)((event.m_y * 100) / size.GetHeight() + 0.5); if ((m_dragging == DSR_HORIZONTAL_TAB && py >= 10 && py <= 90) || (m_dragging == DSR_VERTICAL_TAB && px >= 10 && px <= 90)) { if (m_child[0] == NULL) { Split(px, py); } else { /* It would be nice if moving *this* sash didn't implicitly move the sashes of our children (if any). But this will do. */ wxLayoutConstraints *layout = m_child[0]->m_container->GetConstraints(); if (m_split == DSR_HORIZONTAL_TAB) { layout->height.PercentOf(m_container, wxHeight, py); } else { layout->width.PercentOf(m_container, wxWidth, px); } m_container->Layout(); } } else { if (m_child[0] != NULL) { if ((m_dragging == DSR_HORIZONTAL_TAB && py <= 10) || (m_dragging == DSR_VERTICAL_TAB && px <= 10)) { Unify(1); } else { Unify(0); } } } wxCursor cursor; if (m_split == DSR_HORIZONTAL_TAB) cursor = wxCursor(wxCURSOR_SIZENS); else if (m_split == DSR_VERTICAL_TAB) cursor = wxCursor(wxCURSOR_SIZEWE); else cursor = wxCursor(wxCURSOR_ARROW); m_container->SetCursor(cursor); m_dragging = DSR_NONE; } else if (m_leaf) { m_leaf->OnRelease(event); } }