diff --git a/cpp/src/analysis/interpretation.cpp b/cpp/src/analysis/interpretation.cpp new file mode 100644 index 0000000..58c7cb6 --- /dev/null +++ b/cpp/src/analysis/interpretation.cpp @@ -0,0 +1,234 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * Author: pgess + * Created on June 25, 2018, 3:25 PM + * + * \file interpretation.cpp + * \brief interpretation + */ + +#include "analysis/interpretation.h" + +using namespace std; + +namespace xreate{ +namespace interpretation{ + +TypeAnnotation +collapseFnGroup(const std::list& symbols) { + Gringo::Symbol symbolAny = symbols.front(); + size_t operandsCount = symbolAny.args().size; + + TypeAnnotation resultT; + resultT.__operands.reserve(operandsCount); + + for(size_t operandId = 0; operandId < operandsCount; ++operandId) { + std::list column; + + for(const Gringo::Symbol& row : symbols) { + column.push_back(row.args()[operandId]); + } + + TypeAnnotation operandT = collapseColumn(column); + resultT.__operands.push_back(operandT); + } + + if(resultT.__operands.size() == 1) { + return resultT.__operands.front(); + } + + if(resultT.__operands.size() > 1) { + resultT.__operator = TypeOperator::LIST_NAMED; + return resultT; + } + + return resultT; +} + +TypeAnnotation +collapseColumn(const std::list& symbols) { + TypeAnnotation resultT; + if(!symbols.size()) return resultT; + + Gringo::Symbol symbolAny = symbols.front(); + + switch(symbolAny.type()) { + case Gringo::SymbolType::Num: + { + return TypeAnnotation(TypePrimitive::Num); + } + + case Gringo::SymbolType::Str: + { + return TypeAnnotation(TypePrimitive::String); + } + + case Gringo::SymbolType::Fun: + { + map> fnGroups; + + for(const Gringo::Symbol& row : symbols) { + fnGroups[row.name().c_str()].push_back(row); + } + + TypeAnnotation resultT; + resultT.__operands.reserve(fnGroups.size()); + resultT.bindings.reserve(fnGroups.size()); + + for(const auto& group : fnGroups) { + if(!group.second.size()) continue; + + TypeAnnotation variantT = collapseFnGroup(group.second); + Gringo::Symbol symbolAny = group.second.front(); + string variantName = symbolAny.name().c_str(); + resultT.fields.push_back(variantName); + resultT.__operands.push_back(variantT); + } + + resultT.__operator = TypeOperator::VARIANT; + // if(resultT.__operands.size() == 1) { + // return resultT.__operands.front(); + // } + return resultT; + } + + case Gringo::SymbolType::Inf: + case Gringo::SymbolType::Special: + case Gringo::SymbolType::Sup: + { + break; + } + } + + assert(false); + return TypeAnnotation(); +} + +ExpandedType +dereferenceSlaveType(ExpandedType t, const TranscendLayer* transcend) { + assert(t->__operator == TypeOperator::SLAVE); + const string& domain = t->__valueCustom; + StaticModel model = transcend->query(domain); + if(!model.size()) return ExpandedType(TypeAnnotation()); + + std::list symbols; + for(auto row : model) { + symbols.push_back(row.second); + } + return ExpandedType(collapseFnGroup(symbols)); +} + +Expression +representTransExpression(const Gringo::Symbol& atom, ExpandedType schemaT, TranscendLayer* transcend) { + switch(schemaT->__operator) { + case TypeOperator::NONE: + { + switch(schemaT->__value) { + case TypePrimitive::I8: + case TypePrimitive::I32: + case TypePrimitive::I64: + case TypePrimitive::Num: + case TypePrimitive::Int: + { + return Expression(Atom(atom.num())); + } + + case TypePrimitive::String: + { + return Expression(Atom(atom.string().c_str())); + } + + case TypePrimitive::Invalid: + case TypePrimitive::Bool: + case TypePrimitive::Float: + { + assert(false); + return Expression(); + } + } + break; + } + + case TypeOperator::SLAVE: + { + ExpandedType contentT = dereferenceSlaveType(schemaT, transcend); + return representTransExpression(atom, contentT, transcend); + } + + case TypeOperator::VARIANT: + { + map dictVariants; + for(size_t variantId = 0; variantId < schemaT->fields.size(); ++variantId) { + dictVariants.emplace(schemaT->fields.at(variantId), variantId); + } + + string predicateName = atom.name().c_str(); + assert(dictVariants.count(predicateName)); + + size_t predicateId = dictVariants.at(predicateName); + Expression result(Operator::VARIANT,{}); + result.op = Operator::VARIANT; + result.setValueDouble(predicateId); + + if(!schemaT->__operands.size()) return result; + ExpandedType contentT = schemaT->__operands.at(predicateId).__operator == TypeOperator::SLAVE + ? dereferenceSlaveType(ExpandedType(schemaT->__operands.at(predicateId)), transcend) + : ExpandedType(schemaT->__operands.at(predicateId)); + + //edge case, content's type is LIST_NAMED: + if (contentT->__operator == TypeOperator::LIST_NAMED) { + result.operands.push_back(representTransExpression(atom, contentT, transcend)); + + } else if(!contentT->isValid()) { + return result; + + } else { + assert(atom.args().size); + result.operands.push_back(representTransExpression(atom.args()[0], contentT, transcend)); + } + + return result; + } + + case TypeOperator::LIST_NAMED: + { + const Gringo::SymSpan& operandsRaw = atom.args(); + size_t opCount = operandsRaw.size; + assert(opCount == schemaT->__operands.size()); + + size_t operandId = 0; + std::vector operands; + operands.reserve(opCount); + for(const TypeAnnotation operandT : schemaT->__operands) { + operands.push_back(representTransExpression(operandsRaw[operandId], ExpandedType(operandT), transcend)); + ++operandId; + } + + Expression result(Operator::LIST_NAMED,{}); + result.operands = operands; + result.type = schemaT; + return result; + } + + case TypeOperator::LIST: + case TypeOperator::CALL: + case TypeOperator::CUSTOM: + case TypeOperator::ACCESS: + case TypeOperator::LINK: + { + assert(false); + return Expression(); + } + } + + assert(false); + return Expression(); +} + +} +} //end of xreate namespace \ No newline at end of file diff --git a/cpp/src/analysis/interpretation.h b/cpp/src/analysis/interpretation.h new file mode 100644 index 0000000..8a806a0 --- /dev/null +++ b/cpp/src/analysis/interpretation.h @@ -0,0 +1,31 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * Author: pgess + * Created on June 25, 2018, 3:24 PM + * + * \file interpretation.h + * \brief interpretation + */ + +#ifndef INTERPRETATION_H +#define INTERPRETATION_H + +#include "transcendlayer.h" + +namespace xreate{ +namespace interpretation{ + +TypeAnnotation collapseColumn(const std::list& symbols); +ExpandedType dereferenceSlaveType(ExpandedType t, const TranscendLayer* transcend); + +Expression representTransExpression(const Gringo::Symbol& atom, ExpandedType schemaT, TranscendLayer* transcend); + +} +} +#endif /* INTERPRETATION_H */ + diff --git a/cpp/src/compilation/latex.cpp b/cpp/src/compilation/latex.cpp new file mode 100644 index 0000000..4386fe7 --- /dev/null +++ b/cpp/src/compilation/latex.cpp @@ -0,0 +1,36 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * Author: pgess + * Created on June 23, 2018, 4:33 PM + * + * \file latex.cpp + * \brief latex + */ + +#include "compilation/latex.h" +#include "analysis/interpretation.h" +#include "llvmlayer.h" + +namespace xreate{ +namespace latex{ + +ExpandedType +getSubjectDomain(const std::string& subject, LatexQuery* query){ + std::list&& column = query->getSubjectDomain(subject); + return ExpandedType(interpretation::collapseColumn(column)); +} + +llvm::Value* +ExtraArgsCallStatement::operator() (std::vector&& args, const std::string& hintDecl) { + args.insert(args.end(), __argsLatex.begin(), __argsLatex.end()); + + return __parent->operator ()(std::move(args), hintDecl); +} + +} +} \ No newline at end of file diff --git a/cpp/src/compilation/latex.h b/cpp/src/compilation/latex.h new file mode 100644 index 0000000..8de19d2 --- /dev/null +++ b/cpp/src/compilation/latex.h @@ -0,0 +1,128 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * Author: pgess + * Created on June 23, 2018, 2:51 PM + * + * \file latex.h + * \brief latex + */ + +#ifndef LATEX_H +#define LATEX_H + +#include "compilation/interpretation-instructions.h" +#include "query/latex.h" +#include "pass/compilepass.h" +#include "analysis/interpretation.h" + +namespace xreate{ +namespace latex{ + +ExpandedType +getSubjectDomain(const std::string& subject, LatexQuery* query); + +/** \brief Latex(Late Context)-enabled decorator for IFunctionUnit + * \extends IFunctionUnit + */ +template +class LatexBruteFunctionDecorator: public Parent{ +public: + + LatexBruteFunctionDecorator(ManagedFnPtr f, CompilePass* p) + : Parent(f, p){ + __query = reinterpret_cast (Parent::pass->man->transcend->getQuery(QueryId::LatexQuery)); + } + +protected: + + std::vector + prepareSignature(){ + std::vector&& signature = Parent::prepareSignature(); + + const Demand& demand = __query->getFnDemand(Parent::function->getName()); + signature.reserve(signature.size() + demand.size()); + + for(const std::string& subject: demand){ + llvm::Type* subjectTRaw = Parent::pass->man->llvm->toLLVMType( + getSubjectDomain(subject, __query)); + signature.push_back(subjectTRaw); + } + + return signature; + } + + llvm::Function::arg_iterator + prepareBindings(){ + llvm::Function::arg_iterator fargsI = Parent::prepareBindings(); + + const Demand& demand = __query->getFnDemand(Parent::function->getName()); + for(const std::string& subject: demand){ + std::string argTitle = std::string("latex_") + subject; + fargsI->setName(argTitle); + ++fargsI; + } + + return fargsI; + } + +public: + LatexQuery* __query; +}; + +class ExtraArgsCallStatement: public compilation::ICallStatement{ +public: + + ExtraArgsCallStatement(std::vector argsLatex, compilation::ICallStatement* parent) + : __argsLatex(argsLatex), __parent(parent){ } + + llvm::Value* operator()(std::vector&& args, const std::string& hintDecl = ""); + +private: + std::vector __argsLatex; + compilation::ICallStatement* __parent; +}; + +template +class LatexBruteScopeDecorator: public Parent{ +public: + + LatexBruteScopeDecorator(const CodeScope * const codeScope, compilation::IFunctionUnit* f, CompilePass* compilePass) + : Parent(codeScope, f, compilePass){ } + + compilation::ICallStatement* + findFunction(const Expression& opCall){ + compilation::ICallStatement* stmntCallParent = Parent::findFunction(opCall); + const std::string& calleeName = opCall.getValueString(); + LatexQuery* query = reinterpret_cast (Parent::pass->man->transcend->getQuery(QueryId::LatexQuery)); + + const Demand& fnCalleeDemand = query->getFnDemand(calleeName); + if(!fnCalleeDemand.size()) return stmntCallParent; + + //prepare latex arguments + std::vector argsLatex; + argsLatex.reserve(fnCalleeDemand.size()); + + for(const std::string& subject: fnCalleeDemand){ + ExpandedType subjectT = getSubjectDomain(subject, query); + + Gringo::Symbol decision = query->getDecision(subject, Parent::scope); + const Expression& decisionE = interpretation::representTransExpression( + decision, subjectT, Parent::pass->man->transcend); + Attachments::put(decisionE, subjectT); + argsLatex.push_back(Parent::process(decisionE, subject)); + } + + return new ExtraArgsCallStatement(std::move(argsLatex), stmntCallParent); + } +}; + +} +} //end of namespace xreate::context + +#endif /* LATEX_H */ + diff --git a/cpp/src/query/latex.cpp b/cpp/src/query/latex.cpp new file mode 100644 index 0000000..12f3c65 --- /dev/null +++ b/cpp/src/query/latex.cpp @@ -0,0 +1,80 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * Author: pgess + * Created on June 25, 2018, 12:14 PM + * + * \file latex.cpp + * \brief latex + */ + +#include "query/latex.h" +using namespace std; + +namespace xreate{ +namespace latex{ + +void +LatexQuery::init(TranscendLayer* transcend) { + __transcend = transcend; + + //schema: latex_fn_demand(Fn, Subject) + StaticModel data = __transcend->query("latex_fn_demand"); + for(const auto& entry : data) { + string fnName, subject; + tie(fnName, subject) = __transcend->parse(entry.second); + __demand[fnName].push_back(subject); + } + + //schema: Scope, Subject, Decision + data = __transcend->query("latex_decision"); + for(const auto& entry : data) { + ScopePacked scope; + string subject; + Gringo::Symbol decision; + + tie(scope, subject, decision) = __transcend->parse(entry.second); + __decisions[make_pair(scope, subject)] = decision; + } + + //schema: Subject, Decision + data = __transcend->query("latex_registered_subjects"); + for(const auto& entry : data) { + string subject; + Gringo::Symbol decision; + + tie(subject, decision) = __transcend->parse(entry.second); + __domains[subject].push_back(decision); + } +} + +Demand +LatexQuery::getFnDemand(const std::string& fnName) { + if (!__demand.count(fnName)) return Demand(); + return __demand.at(fnName); +} + +Gringo::Symbol +LatexQuery::getDecision(const std::string& subject, const CodeScope* scopeCaller) { + ScopePacked scopeP = __transcend->pack(scopeCaller); + + if(__decisions.count(make_pair(scopeP, subject))){ + //found static decision + return __decisions.at(make_pair(scopeP, subject)); + } + + //... <- вытащить late decision +} + +std::list +LatexQuery::getSubjectDomain(const std::string& subject) { + assert(__domains.count(subject)); + return __domains.at(subject); +} + +} +} \ No newline at end of file diff --git a/cpp/src/query/latex.h b/cpp/src/query/latex.h new file mode 100644 index 0000000..7163ef4 --- /dev/null +++ b/cpp/src/query/latex.h @@ -0,0 +1,43 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/** + * \file query/context.h + * \brief Represents reasoner's solution on [Context](/w/concepts/context) + * + * \class xreate::latex::LatexQuery + */ + +#ifndef LATEXQUERY_H +#define LATEXQUERY_H + +#include "transcendlayer.h" +#include + +namespace xreate{ +namespace latex{ + +typedef std::list Demand; + +class LatexQuery: public IQuery{ +public: + Demand getFnDemand(const std::string& fnName); + Gringo::Symbol getDecision(const std::string& subject, const CodeScope* scopeCaller); + std::list getSubjectDomain(const std::string& subject); + void init(TranscendLayer* transcend); + +private: + TranscendLayer* __transcend; + std::map __demand; + std::map, Gringo::Symbol> __decisions; + std::map> __domains; +}; + +} +} + +#endif /* LATEXQUERY_H */ + diff --git a/cpp/tests/latex.cpp b/cpp/tests/latex.cpp new file mode 100644 index 0000000..4148fe8 --- /dev/null +++ b/cpp/tests/latex.cpp @@ -0,0 +1,201 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + * + * Author: pgess + * Created on June 25, 2018, 5:42 PM + * + * \file latex.cpp + * \brief Testing of latex + */ + +#include "xreatemanager.h" +#include "pass/compilepass.h" +#include "transcendlayer.h" +#include "compilation/latex.h" +#include "aux/xreatemanager-decorators.h" +#include "compilation/scopedecorators.h" +#include "llvmlayer.h" + +#include +#include + +using namespace xreate::latex; +using namespace xreate::compilation; +using namespace xreate; +using namespace std; + +TEST(Latex, Analysis1) { + std::string program = + R"CODE( + import raw("scripts/cfa/context.lp"). + + a = function:: int + { + context:: forC(a). + c() + } + + b = function:: int + { + context:: forC(b). + c() + } + + c = function:: int {0} + + main = function:: int; entry + { + a() + b() + } + )CODE"; + + std::unique_ptr man(details::tier1::XreateManager::prepare(move(program))); + + CodeScope* blockC = man->root->findFunction("c")->getEntryScope(); + auto blockCP = man->transcend->pack(blockC); + boost::format formatAlias("alias(%1%, %2%)."); + man->transcend->addRawScript((formatAlias % blockCP % "blockC").str()); + man->transcend->addRawScript( + R"SCRIPT( + latex_scope_demand(BlockC, forC):- alias(BlockC, blockC). + latex_registered_subjects(forC, Variant):- bind_scope(_, Variant, strong); Variant = forC(_). + )SCRIPT"); + man->analyse(); + + ASSERT_EQ(1, man->transcend->query("latex_fn_demand").size()); + ASSERT_EQ(2, man->transcend->query("latex_decision").size()); +} + +TEST(Latex, Compilation1) { + std::string program = + R"CODE( + + a = function:: int + {0} + + main = function:: int; entry + { + a() + } + )CODE"; + + string script = + R"SCRIPT( + latex_fn_demand(%1%, subject1). + latex_decision(%2%, subject1, 5). + latex_registered_subjects(subject1, 1). + latex_registered_subjects(subject1, 5). + )SCRIPT"; + + typedef LatexBruteFunctionDecorator FnImpl; + typedef LatexBruteScopeDecorator> ScopeImpl; + + std::unique_ptr man(details::tier1::XreateManager::prepare(move(program))); + ScopePacked scopeMainP = man->transcend->pack(man->root->findFunction("main")->getEntryScope()); + boost::format format(script); + man->transcend->addRawScript((format % "a" % scopeMainP).str()); + man->transcend->registerQuery(new LatexQuery(), QueryId::LatexQuery); + man->analyse(); + + std::unique_ptr compiler(new compilation::CompilePassCustomDecorators(man.get())); + compiler->run(); + man->llvm->print(); +} + +TEST(Latex, Full1) { + std::string program = + R"CODE( + import raw("scripts/cfa/context.lp"). + + a = function:: int + { + context:: forC(a). + c() + } + + b = function:: int + { + context:: forC(b). + c() + } + + c = function:: int {0} + + main = function:: int; entry + { + a() + b() + } + )CODE"; + + string script = + R"SCRIPT( + alias(%1%, scopeC). + latex_scope_demand(ScopeC, forC) :- alias(ScopeC, scopeC). + latex_registered_subjects(forC, forC(a)). + latex_registered_subjects(forC, forC(b)). + )SCRIPT"; + + typedef LatexBruteFunctionDecorator FnImpl; + typedef LatexBruteScopeDecorator> ScopeImpl; + + std::unique_ptr man(details::tier1::XreateManager::prepare(move(program))); + ScopePacked scopeMainP = man->transcend->pack(man->root->findFunction("main")->getEntryScope()); + auto scopeCP = man->transcend->pack(man->root->findFunction("c")->getEntryScope()); + boost::format format(script); + man->transcend->addRawScript((format %scopeCP).str()); + man->transcend->registerQuery(new LatexQuery(), QueryId::LatexQuery); + man->analyse(); + + std::unique_ptr compiler(new compilation::CompilePassCustomDecorators(man.get())); + compiler->run(); + man->llvm->print(); +} + +TEST(Latex, TransitFn1){ + std::string program = + R"CODE( + import raw("scripts/cfa/context.lp"). + + branchA = function:: int + { + context:: sink(a). + fnTransit() + } + + branchB = function:: int + { + context:: sink(b). + fnTransit() + } + + fnSink = function:: int {0} + fnTransit = function:: int {fnSink()} + + main = function:: int; entry + { + branchA() + branchB() + } + )CODE"; + + string script = + R"SCRIPT( + alias(scopeSink, %1%). + latex_scope_demand(ScopeSink, sink):- alias(scopeSink, ScopeSink). + latex_registered_subjects(sink, sink(a)). + latex_registered_subjects(sink, sink(b)). + )SCRIPT"; + + typedef LatexBruteFunctionDecorator FnImpl; + typedef LatexBruteScopeDecorator> ScopeImpl; + + std::unique_ptr man(details::tier1::XreateManager::prepare(move(program))); + auto scopeSinkP = man->transcend->pack(man->root->findFunction("fnSink")->getEntryScope()); + boost::format format(script); + man->transcend->addRawScript((format %scopeSinkP).str()); + man->transcend->registerQuery(new LatexQuery(), QueryId::LatexQuery); + man->analyse(); + + std::unique_ptr compiler(new compilation::CompilePassCustomDecorators(man.get())); + compiler->run(); + man->llvm->print(); +} \ No newline at end of file diff --git a/documentation-api/latereasoning.graphml b/documentation-api/latereasoning.graphml new file mode 100644 index 0000000..f4f3633 --- /dev/null +++ b/documentation-api/latereasoning.graphml @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Late Reasoning +Diagram + + + + + + + + + + + + + + + + + LateReasoning +Scope + + + + + + + fvffdfd + + + + + + + vdffldkjfd +fdfdfd + + + + + + + + + + + + + + + + + + + + + DFAPassDecorator + + + + + + + fvffdfd + + + + + + + vdffldkjfd +fdfdfd + + + + + + + + + + + + + + + + + + + + + DFAPass + + + + + + + + + + + + + + + + + + + + + ICodeScope + + + + + + + + + + + + + + + + + + + + + LateSymbol +Recognized + + + + + + + + + + + + + + + + + + + + + DFAGraph + + + + + + + + + + + + + + + + + + + + + LateReasoning +Compiler + + + + + + + + + + + + + + + + + + + + + CompilePass + + + + + + + + + + + + + + + + + + + + + LateReasoning +Transcend +Decorator + + + + + + + + + + + + + + + + + + + + + Transcend +Layer + + + + + + + + + + + + + + + + + + + + + LateAnnotations +Group + + + + + + + + + + + + + + + + + + + + + Late +Annotation + + + + + + + + + + + + + + + + + + + + + Polymorph +Query + + + + + + + + + + + + + + + + + + + + + LateBindingT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/cfa/context.lp b/scripts/cfa/context.lp new file mode 100644 index 0000000..9fd0394 --- /dev/null +++ b/scripts/cfa/context.lp @@ -0,0 +1,82 @@ +% This Source Code Form is subject to the terms of the Mozilla Public +% License, v. 2.0. If a copy of the MPL was not distributed with this +% file, You can obtain one at http://mozilla.org/MPL/2.0/. + +%% INPUT: +%% - latex_scope_demand(Scope, Subject) +%% Initial demand from clients +%% +%% - latex_registered_subjects(Subject, PossibleDecision) +%% Clients register possible decisions for respective subjects +%% +%% OUTPUT: +%% - latex_fn_demand(Fn, Subject) +%% Which functions demand hidden latex arguments +%% +%% - latex_decision(Scope, Subject, Decision) +%% Provided decisions, values for hidden latex arguments + +% CONTEXT PROPAGATION +%=========================================================== + +% nested scope propagation: +% test: CFA.Context1 +bind_scope(Scope, Context, Info):- + bind_scope(ScopeParent, Context, Info); + cfa_parent(Scope, scope(ScopeParent)). + +% Strong or Uniform inter-function propagation: +bind_scope(Scope, Context, Info):- + bind_scope(ScopeParent, Context, Info): cfa_call(ScopeParent, FnCurrent); + cfa_parent(Scope, function(FnCurrent)); cfa_call(_, FnCurrent); + bind_scope(_, Context, Info); scope(Scope). + +% weak inter-function propagation +bind_scope(Scope, Context, weak(ScopeParent)):- + not bind_scope(Scope, Context, strong); + bind_scope(ScopeParent, Context, strong); + cfa_call(ScopeParent, FnCurrent); + cfa_parent(Scope, function(FnCurrent)). + + +% DEMAND +%Tests: CFA.Latex_SimpleFork1 +%=========================================================== + +%demand propagations: scope level +latex_scope_demand(Scope, Subject):- + latex_scope_demand(ScopeChild, Subject); + cfa_parent(ScopeChild, scope(Scope)). + +%propagation: fn level +latex_fn_demand(Fn, Subject):- + latex_scope_demand(ScopeFnBody, Subject); + cfa_parent(ScopeFnBody, function(Fn)). + +%propagation: inter-fn level +latex_scope_demand(Scope, Subject):- + latex_fn_demand(FnCallee, Subject); + not latex_decision(Scope, Subject, _); + cfa_call(Scope, FnCallee). + +% DECISIONS +%Tests: CFA.Latex_SimpleFork1 +%=========================================================== + +latex_decision(Scope, Subject, Decision):- + latex_fn_demand(FnCallee, Subject); + bind_scope(Scope, Decision, strong); + cfa_call(Scope, FnCallee); + latex_registered_subjects(Subject, Decision). + +%late decision +late(s(ScopeCaller, 0), (DecisionS), (AnyDecision), latex_decision(ScopeCaller, Subject, AnyDecision)):- + scope_fn(ScopeCaller, FnCaller); + latex_fn_signature(FnCaller, Subject, DecisionS); + + cfa_call(ScopeCaller, FnCallee); + latex_fn_demand(FnCallee, Subject); + latex_registered_subjects(Subject, AnyDecision). + + + diff --git a/scripts/cfa/latex1.xreate b/scripts/cfa/latex1.xreate new file mode 100644 index 0000000..de4486a --- /dev/null +++ b/scripts/cfa/latex1.xreate @@ -0,0 +1,39 @@ +guard:: guardA { + fnGuarded = function :: int + {0} +} + +guard:: guardB { + fnGuarded = function :: int + {1} +} + +fnEntry= function:: int; entry +{ + fnA() + fnB() +} + +fnA = function:: int +{ + context:: guards(guardA). + fnInterim() +} + +fnInterim=function:: int +{ + fnMain() +} + +fnB = function:: int +{ + context:: guards(guardB). + fnMain() +} + +fnMain = function:: int +{ + switch late(argGuard):: int + { + fnGuarded() + } +} diff --git a/scripts/cfa/test2.assembly.lp b/scripts/cfa/test2.assembly.lp new file mode 100644 index 0000000..567c43e --- /dev/null +++ b/scripts/cfa/test2.assembly.lp @@ -0,0 +1,10 @@ + +dfa_callguard(InstSymbRet, Guard):- %static local decision + bind_scope(Scope, callguard(Guard), strong); + bind(InstSymbRet, dfa_polym(cntxt)); + InstSymbRet = s(_, _, Scope). + +%Register manual demand +kleo_registered_subjects(Scope, spec(FnCallee), Guard):- + bind_scope(Scope, kleo_manual_demand(FnCallee), strong); + cfa_function_specializations(FnCallee, Guard). diff --git a/scripts/cfa/test2.xreate b/scripts/cfa/test2.xreate new file mode 100644 index 0000000..5eeb13b --- /dev/null +++ b/scripts/cfa/test2.xreate @@ -0,0 +1,101 @@ +import raw ("scripts/latereasoning/context-v1.lp"). +import raw ("scripts/latereasoning/test2.assembly.lp"). + +Annotation = type variant { + Num:: int, + String:: string, + Func:: {name::string, arguments::[Annotation]} +}. + +FnControl = type variant { + Variant1, Variant2 +}. + +main = function:: int; entry { + funcA() + funcB() :: int +} + +funcA = function::int{ + context:: variant1. + + testedFunc(prepareCtrlArg("testedFunc", intrinsic query_scope())) +} + +funcB = function::int { + context:: variant2. + + testedFunc(prepareCtrlArg("testedFunc", intrinsic query_scope())) +} + +testedFunc = function(ctrl::FnControl):: int { + context:: kleo_manual_demand(funcC). + + switch variant(ctrl)::int + case(Variant1){context:: callguard(variant1). funcC():: int; dfa_polym(cntxt)} + case(Variant2){context:: callguard(variant2). funcC():: int; dfa_polym(cntxt)} +} + +guard:: variant1 { + funcC = function:: int {1} +} + +guard:: variant2 { + funcC = function:: int {2} +} + +selectSecond = function (db:: [Annotation], argFirst::Annotation):: Annotation; interpretation(force) { + resultWrong = String("wrong")::Annotation. + + loop fold(db->entry:: Annotation, resultWrong->result):: Annotation{ + switch variant(entry):: Annotation + case (Num) {resultWrong} + case (String) {resultWrong} + + case (Func) { + if(entry["arguments"][0] == argFirst)::Annotation + {entry["arguments"][1]::Annotation; break} + else {result} + } + } +} + +selectThird = function (db:: [Annotation], argFirst::Annotation, argSecond:: Annotation):: Annotation; interpretation(force){ + resultWrong = String("wrong")::Annotation. + + loop fold(db->entry:: Annotation, resultWrong->result):: Annotation{ + switch variant(entry):: Annotation + case (Num) {resultWrong} + case (String) {resultWrong} + + case (Func) { + if(entry["arguments"][0] == argFirst)::Annotation{ + if (entry["arguments"][1] == argSecond):: Annotation{ + entry["arguments"][2]:: Annotation; break + } else {result} + } else {result} + } + } +} + +prepareCtrlArg = function(fnName:: string; interpretation(force), + scope:: Annotation; interpretation(force)) + :: FnControl { + + demandsDb = intrinsic query("kleo_fn_demand")::[Annotation]. + decisionsDb = intrinsic query("kleo_scope_decision")::[Annotation]. + + demandKey = selectSecond(demandsDb, Func({name = fnName, arguments = []})):: Annotation. + decisionKey = Func({name="kleo_arg", arguments=[demandKey]}):: Annotation. + + decision = selectThird(decisionsDb, scope, decisionKey)::Annotation. + + switch variant(decision):: FnControl + case (Num) {Variant1()} + case (String) {Variant1()} + case (Func) { + switch(decision["name"]):: FnControl + case("variant1") {Variant1()} + case("variant2") {Variant2()} + case default {Variant1()} + } +} diff --git a/scripts/virtualization/test2.xreate b/scripts/virtualization/test2.xreate new file mode 100644 index 0000000..83d68ef --- /dev/null +++ b/scripts/virtualization/test2.xreate @@ -0,0 +1,39 @@ + +// Different sizos get different prefixes + +SIZO = type slave sizo. + +findSizoId = function(key::Annotation):: int; interpretation(force){ + dict = intrinsic query("dictSizos")::[Annotation]. + + id = loop fold(dict->entryAnn::Annotation, 0->id):: int { + entry = extractDictEntry(entryAnn):: DictEntry. + + if(entry[0] == key):: int { entry[1] } else { id } + }. + + id +} + +findSizoPrefx = function(sizo:: SIZO):: string +{ + id = findSizoId(sizo). + + buf = "0000"::string. + seq + { sprintf(buf, "%d", id).} + { buf } +} + +openfile = function +{ + domCurrent = query context:: SIZO. + prefix = findSizoPrefx(domCurrent):: string. + + fopen(prefixStr + fileName) +} + +writefile = function +{ + +}