Implementing a list of evaluation contexts? - kframework

I'm attempting to implement an evaluation stack as a list of KItems.
I have a rule that adds evaluation contexts into the stack:
rule <k> X:KVar V:Val ~> E => !DOSOMETHING! </k>
<stack> ES => E ~> ES </stack>
However, I encounter a bug when adding an empty E to the stack.
I attempted to extend KItem with a constructor:
syntax KItem ::= "MyContext" KItem
However, this causes rules of the form
rule <k> !DOSOMETHING! => !V:KVar ~> E </k>
<stack> MyContext E ~> ES => ES </stack>
to fail pattern matching.
Is there a correct way of implementing a stack of evaluation contexts like I'm trying to do?
EDIT:
syntax Exp ::= Int | KVar | Exp "+" Exp [seqstrict(1,2), left]
| "!DOSOMETHING!"
| "(" Exp ")" [bracket]
syntax KResult ::= Int
configuration
<T>
<k> $PGM:Exp </k>
<stack> .K </stack>
</T>
syntax KItem ::= "MyContext" KItem
rule I1:Int + I2:Int => I1 +Int I2
rule <k> X:KVar + V ~> E:KItem => !DOSOMETHING! </k>
<stack> ES => MyContext E ~> ES </stack>
rule <k> V + X:KVar ~> E:KItem => !DOSOMETHING! </k>
<stack> ES => MyContext E ~> ES </stack>
rule <k> !DOSOMETHING! => 0 ~> E </k>
<stack> MyContext E:KItem ~> ES => ES </stack>
would immediately get stuck on a file:
1 + X + 3 + X + 5
If we remove the MyContext,
rule <k> X:KVar + V ~> E:KItem => !DOSOMETHING! </k>
<stack> ES => E ~> ES </stack>
rule <k> V + X:KVar ~> E:KItem => !DOSOMETHING! </k>
<stack> ES => E ~> ES </stack>
rule <k> !DOSOMETHING! => 0 ~> E </k>
<stack> E:KItem ~> ES => ES </stack>
the semantics gets stuck with x + 1.
I suspect I'm actually talking about different issues here. But how does one pattern match the evaluation context correctly?

It looks like your k cell contains a single KItem, which is the addition expression, but the only rules that match addition at the top of the k cell require a second KItem to be present and thus do not apply if there is only one KItem. Did you mean to match a variable of sort K instead? The k cell normally contains a term of sort K, which is a sort representing a cons list of KItem of which ~> is the concatenation operator and .K is the list unit. For convenience, the user can write terms of sort K as if it is an associative list so long as they don't actually match a term of sort K on top of another term, but the rules that you wrote only match a list with exactly two elements. If you intend for E to match the tail of the list, you need to change the sort of E to K.

Related

Structural Operational Semantics in K?

Is there syntax for rules such as:
P => P'
-----------
P + Q => P'
Or would I need to redefine the semantics with evaluation contexts?
There is a book on Big-Step SOS from 2010 on the Kframework website using old syntax:
crl < A1 / A2,Sigma > => < I1 /Int I2 >
if < A1,Sigma > => < I1 > /\ < A2,Sigma > => < I2 > /\ I2 =/= 0 .
It appears to do what I'm looking for, but I'm not sure if new syntax exists for it.
You could do something like this (psuedocode):
configuration <k> $PGM </k>
<state> WHATEVER_YOUR_STATE_IS </state>
syntax KItem ::= evaluateInContext ( Exp , StateCell )
syntax Exp ::= Exp "/" Exp | "HOLE1" | "HOLE2" | Value
syntax Value ::= Int
rule <k> A1 / A2 => evaluateInContext(A1, <state> STATE </state>) ~> evaluateInContext(A2, <state> STATE </state>) ~> HOLE1 / HOLE2 ... </k>
<state> STATE </state>
rule <k> evaluateInContext(A, <state> STATE </state>) => A ... </k>
<state> _ => STATE </state>
rule <k> V:Value ~> evaluateInContext(A, S) => evaluateInContext(A, S) ~> V ... </k>
rule <k> V:Value ~> V':Value ~> HOLE1 / HOLE2 => V' /Int V ... </k>
So you can always pass around configurations as first-class citizens.
An example of this is in KEVM, where we use this sort of mechanism to save/retrieve a list of callstacks.
Update to address comment.
If you want to check that a subterm makes a state transition, you can change it to something like this (psuedo-code again):
syntax KItem ::= "evaluated?" "(" Exp "," State ")"
rule <k> evaluateInContext(A, <state> STATE </state>) => A ~> evaluated?(A, <state> STATE </state> ... </k>
<state> _ => STATE </state>
rule <k> V:Value ~> evaluated?(A, <state> STATE </state>) => DO_SOMETHING_WHEN_EVALUATED ... </k>
rule <k> NOT_VALUE:Exp ~> evaluated?(A, <state> STATE </state>) => DO_SOMETHING_WHEN_NOT_EVALUATED ... </k>
Note that here I'm using "has reduced to sort Value" to determine if it's "evaluated", but you can of course have any side-condition you like for determining that.

NEST (ElasticSearch) Terms Aggregation does not acknowledge the Query

I have a search request as below:
var response = client.Search<ProductElastic>(s => s
.Query(q => q
.Bool(b => b
.Should(mu => mu
.Match(m => m
.Field(f => f.title)
.Boost(1.5)
.Query(inputfilter.q)
), mu => mu
.Match(m => m
.Field(f => f.content)
.Query(inputfilter.q)
)
)
)
)
.Aggregations(a => a
.Terms("doctype_i", he => he
.Field(g => g.doctype_i)
)
.Terms("category_i", e => e
.Field(ge => ge.category_i)
.Size(100)
)
)
);
inputfilter.q holds the search term. When inputfilter.q is null it returns all the results and my aggregation bucket numbers are accurately represented. When inputfilter.q is defined (ex. searching for "test") it refines the results set, however, my aggregation buckets still give me the full numbers as before, as if nothing was searched for. For the record, doctype_i and category_i are integer type fields in Elastic.
How do I make my .Aggregations acknowledge the .Query so the aggregation buckets reflect numbers based on the results set?

Linear grammar, derive a word

Assuming a right-linear grammar is given how would you show the steps to derive a word? For example if I had the grammer:
S -> aA
A -> bA
A -> aB
B -> cB
B -> a
And I wanted to constuct the word abbbacca. How would I show my step derivertation? Would it be:
S => A => A => A => A => B => B => B
or somethiong more akin to:
aA => abA => abbA => abbbA => abbbaB => abbbacB => abbbaccB => abbbacca
Converting comments to an answer so the question can disappear from the unanswered lists ...
The form
S => aA => abA => abbA => abbbA => abbbaB => abbbacB => abbbaccB => abbbacca
is the more usual, and preferable, way to show the derivation. For extra credit, especially so with larger grammars, it may also be useful to show the label of the rule applied on the derivation arrow, something like
S =(1)=> aA
Of course, for this to be really useful the rules have to have labels !

Test pre-requisites for tabular tests; how does tabular work?

Let's say I am attempting to test an api that is supposed to handle presence or absence of certain object fields.
Let's say I have tests like so:
(def without-foo
{:bar "17"})
(def base-request
{:foo "12"
:bar "17"})
(def without-bar
{:foo "12"})
(def response
{:foo "12"
:bar "17"
:name "Bob"})
(def response-without-bar
{:foo "12"
:bar ""
:name "Bob"})
(def response-without-foo
{:bar "17"
:foo ""
:name "Bob"})
(facts "blah"
(against-background [(external-api-call anything) => {:name => "Bob"})
(fact "base"
(method-under-test base-request) => response)
(fact "without-foo"
(method-under-test without-foo) => response-without-foo)
(fact "without-bar"
(method-under-test without-bar) => response-without-bar))
This works as you would expect and the tests pass. Now I am attempting to refactor this using tabular like so:
(def request
{:foo "12"
:bar "17"})
(def response
{:foo "12"
:bar "17"
:name "Bob"})
(tabular
(against-background [(external-api-call anything) => {:name "Bob"})]
(fact
(method-under-test (merge request ?diff) => (merge response ?rdiff))
?diff ?rdiff ?description
{:foo nil} {:foo ""} "without foo"
{} {} "base case"
{:bar nil} {bar ""} "without bar")
Which results in:
FAIL at (test.clj:123)
Midje could not understand something you wrote:
It looks like the table has no headings, or perhaps you
tried to use a non-literal string for the doc-string?
Ultimately I ended up with:
(tabular
(fact
(method-under-test (merge request ?diff) => (merge response ?rdiff) (provided(external-api-call anything) => {:name "Bob"}))
?diff ?rdiff ?description
{:foo nil} {:foo ""} "without foo"
{} {} "base case"
{:bar nil} {bar ""} "without bar")
Which passes. My question is. How does the tabular function differ from the facts function, and why does one of them accept an against-background while the other blows up?
You need to have following nesting if you want to establish background prerequisites for all your tabular based facts:
(against-background [...]
(tabular
(fact ...)
?... ?...))
For example:
(require '[midje.repl :refer :all])
(defn fn-a []
(throw (RuntimeException. "Not implemented")))
(defn fn-b [k]
(-> (fn-a) (get k)))
(against-background
[(fn-a) => {:a 1 :b 2 :c 3}]
(tabular
(fact
(fn-b ?k) => ?v)
?k ?v
:a 1
:b 3
:c 3))
(check-facts)
;; => All checks (3) succeeded.
If you want to have a background prerequisite per each tabular case you need to nest it as following:
(tabular
(against-background [...]
(fact ...))
?... ?...)
It's important to have the table just under tabular level, not nested in against-background or fact.
For example:
(require '[midje.repl :refer :all])
(defn fn-a []
(throw (RuntimeException. "Not implemented")))
(defn fn-b [k]
(-> (fn-a) (get k)))
(tabular
(against-background
[(fn-a) => {?k ?v}]
(fact
(fn-b ?k) => ?v))
?k ?v
:a 1
:b 2
:c 3)
(check-facts)
;; => All checks (3) succeeded.
In your code it looks like the tabular data is not positioned correctly (parentheses, brackets and curly braces are not balanced correctly so it's impossible to say what exactly is incorrect).

Fluent Nhibernate QueryOver and Joins

I'm in the process of learning Fluent nHibernate. I'm having trouble with building a query thats not quite the same as the classic examples I've found online. Typically I've found this example:
IQueryOver<Cat,Cat> catQuery =
session.QueryOver<Cat>(() => catAlias)
.JoinAlias(() => catAlias.Kittens, () => kittenAlias)
.Where(() => catAlias.Age > 5)
.And(() => kittenAlias.Name == "Tiddles");
So from what I understand in this example a Cat object is being returned after being joined on Kittens and then filtered using the kittens name and the cat's age. And the join works because the Cat object has a property called Kittens.
An example of what I'm trying to do would look like this:
Forest f = null;
Tree t = null;
ForestsFound = session.QueryOver<Forest>(() => f)
.JoinAlias(() => t.Forest, () => f)
.Where(() => t.NumberOfTrees > 1000)
.List<Forest>()
.ToList<Forest>();
A forest is essentially a lookup table, it's the Tree that has a link to what forest the tree is in but I want to return a distinct list of forests. So in regular sql it would look like:
select f.*
from Forest f
inner join Tree t
on t.Forest_id = f.ID
where t.NumberOfTrees > 1000
If you have a relationship from Forest -> Trees then you can do this:
Forest f = null;
Tree t = null;
ForestsFound = session.QueryOver<Forest>(() => f)
.JoinAlias(() => f.Trees, () => t)
.Where(() => t.NumberOfTrees > 1000)
.List<Forest>();