Stateful rules that manipulate global state in K? - kframework

Does K have a notion of global state that rules can access?
e.g.
Say a configuration C => C'. I want to transition iff C' doesn't exist in a set of explored states, and then update the global set of explored states by adding C'to it.
I'm trying to explore all reachable states of a program non-deterministically (using the --search option). However, each path explored is independent, which means each path would not be aware of configurations seen in the other paths if I were to pass the explored set in the configuration itself.
If there's no global state, what's the best practice for this kind of behaviour? Is there a way to non-deterministically explore transitions within some bigger environment that each independent path is able to access?

You can always emulate this behavior yourself if needed, but it is quite cumbersome and a little bit error prone:
configuration <myConfig>
<k> $PGM:Pgm </k>
<someOtherCells> .SomeOtherSort </someOtherCells>
</myConfig>
<states> .List </states>
syntax Pgm ::= "saveConfig" | "loadConfig" Int | "isExplored?"
syntax Bool ::= "#isExplored?" "(" MyConfigCell "," List ")"
rule <myConfig> <k> saveConfig => . ... </k> ... </myConfig> #as CONFIGURATION
<states> ... (.List(CONFIGURATION)) </states>
rule (<myConfig> <k> loadConfig IDX ~> REST </k> ... </myConfig> => STATES[IDX])
<states> STATES </states>
requires IDX <Int size(STATES)
rule <myConfig> <k> isExplored? => #isExplored?(CONFIGURATION, STATES) ... </k> ... </myConfig> #as CONFIGURATION
<states> STATES </states>
Then you need to provide the definition of whether a state has been explored or not via #isExplored? function. Direct equality may work (using ==K) but likely not. Chances are you want to only actually compare some subset of the cells there.
Unfortunately, this state-folding functionality is not built into the Haskell backend yet. It could, of course, automatically check every new visited state to see if it's one that has been explored before, and if so stop searching on that execution path. If you need this functionality, please open an issue at https://github.com/kframework/kore repository, and explain your use-case. No promises on it being implemented soon, but it would be nice for us to know how people want to use the tool.

Related

How do I generate numbered lists with pod?

Looking at https://docs.raku.org/language/pod#Lists. I don't see a way to create a numbered list:
one
three
four
Is there an undocumented way to do it?
There is not currently (as of January 2022) an implemented way to use ordered list in Pod6.
The historical design documents contain Pod6 syntax for ordered lists and, as far as I know, this remains something that we'd like to add. Once that syntax is implemented, you'll be able to write something like:
=item1 # Animal
=item2 # Vertebrate
=item2 # Invertebrate
=item1 # Phase
=item2 # Solid
=item2 # Liquid
=item2 # Gas
This would produce output along the lines of:
1. Animal
1.1 Vertebrate
1.2 Invertebrate
2. Phase
2.1 Solid
2.2 Liquid
2.3 Gas
(Though the exact syntax for rendering the list would be up to the implementation of the Pod renderer.)
But until that's implemented, there isn't any way to use Pod6 syntax to create an ordered list.
Edit:
I just checked the actual parsed Pod6, and it looks like (to my surprise) the ordered list syntax I showed above actually is parsed internally. For example, running say $=pod[5].raku with the Pod6 shows the following (based on the =item2 # Liquid line):
Pod::Item.new(level => 2, config => {:numbered(1)}, contents => [Pod::Block::Para.new(config => {}, contents => ["Liquid"])])
So the parsing work is in place; it's just the Pod::To::_ renderer that need to add support. (And there could even be some out there that have that support. I do know that neither Rakudo's Pod::To::Text nor Raku's Pod::To::HTML (v0.8.1) currently render ordered lists, however.)
Workarounds
Depending on the output formats you're targeting, you could of course write the ordered list yourself (pretty easy if you're rendering to plain text, more annoying to do if you're printing to HTML). This does, of course, sacrifice Pod6's multi-output-format support, which is one of its key features.
For a workaround that doesn't sacrifice Pod's multi-output nature, you'd probably want to look into manipulating/reformatting the Pod text programmatically. If you do so, the docs to start with are the Pod6 section on accessing Pod and the (unfortunately very short) section on the DOC phaser.
Just use a list and a loop?
my #list = [ (1, 2, 3), (1, 2, ),
[<a b c>, <d e f>],
[[1]]];
for #list -> #element {
say "{#element} → {#element.^name}";
for #element -> $sub-element {
say $sub-element;
}
}
# OUTPUT:
#1 2 3 → List
#1
#2
#3
#1 2 → List
#1
#2
#a b c d e f → Array
#(a b c)
#(d e f)
#1 → Array
#1

The relative clause (which) in GF

"Play Toy Story which was published last year"
Sentence = mkUtt( mkImp (mkVP
(mkV2 "play")
(mkNP (mkCN
(mkCN (mkN "Toy Story"))
(mkS pastTense simultaneousAnt(mkCl (mkVP
(mkV2 "publish")
(mkNP (mkCN (mkN "last yser")))
)))
))
));
When creating a relative clause sentence in GF it always the syntax S for sentence will add that between the two of the sentences is there is any way to replace that with which.
First of all, the structure you made isn't a relative clause, but this structure:
mkCN : CN -> S -> CN -- rule that she sleeps
Relative clause has the type RS in the RGL.
How to construct an actual RS
Here I build the RS gradually. Feel free to put these steps back to a single expression, if you wish so, but I find it clearer to to things like this.
oper
last_year_Adv : Adv = ParadigmsEng.mkAdv "last year" ;
published_last_year_VP : VP = mkVP (passiveVP (mkV2 "publish")) last_year_Adv ;
which_is_published_last_year_RCl : RCl = mkRCl which_RP published_last_year_VP ;
which_was_published_last_year_RS : RS = mkRS pastTense which_is_published_last_year_RCl ;
lin
play_TS = mkUtt (mkImp (mkVP
(mkV2 "play")
(mkNP
(mkNP (mkPN "Toy Story"))
which_was_published_last_year_RS)
)
) ;
Now when we test it on the GF shell, we see that despite the name, which_RP is actually "that".
> l play_TS
play Toy Story , that was published last year
How to change "that" into "which"
The first thing to check when you want to create a new lexical item is Paradigms module. Unfortunately, there is no mkRP for English. Things like relative pronouns are usually thought of as closed class: there's only a small, fixed amount of them. Other examples of closed classes are basic numerals (you can't just make up a new integer between 4 and 5!) and determiners. Contrast this to open classes like nouns, verbs and adjectives, those pop up all the time. For open classes, Paradigms modules have many options. But not for closed classes, like relative pronouns.
So if Paradigms doesn't help, the next thing to check is the language-specific Extra module.
Check language-specific Extra modules
If you have the RGL source on your own computer, you can just go to the directory gf-rgl/src/english and grep for which. Or you can use the RGL browser to search for interesting functions.
And there is indeed a relative pronoun in ExtraEng, also called which_RP. (There is also one called who_which_RP.) So now you can do these modifications in your grammar:
concrete MyGrammarEng of MyGrammar =
open SyntaxEng,
ParadigmsEng,
ExtraEng -- Need to open ExtraEng in the concrete!
in ** {
-- … as usual, except for
oper
which_is_published_last_year_RCl : RCl =
mkRCl ExtraEng.which_RP -- Use the ExtraEng.which_RP!
published_last_year_VP ;
And the rest of the code is like before. This produces the result you want.
> l play_TS
play Toy Story , which was published last year
Last-resort hack
So you have looked in all possible modules and found nothing. Consider making it into an issue in the gf-rgl repository, if it's something that's clearly wrong or missing.
But in any case, here's a general, unsafe hack to quickly construct what you want.
First, let's look at the lincat of RP in CatEng, {s : RCase => Str ; a : RAgr}. Then let's look at its implementation in RelativeEng. There you see also the explanation why it's always "that": unlike who and which, "that" works for animate and inanimate NPs.
So I would do this to force the string "which":
oper
myWhich_RP : RP = which_RP ** {s = table {_ => "which"}} ;
The ** syntax means record extension. We use all other fields from the original which_RP, but in the s field, we put a table whose all branches contain the string "which". (You can read more about this technique in my blog.)
Then we use the newly defined myWhich_RP in forming the relative clause:
oper
which_is_published_last_year_RCl : RCl = mkRCl myWhich_RP published_last_year_VP ;
This works too, but it's unsafe, because whenever the RGL changes, any code that touches the raw implementation may break.

adding (|) functionality to determiner on GF

On GF writing sentences' tree often encounter many options where multiple prepositions could be used in the same tree such as
Download it on my phone
Download it to my phone
Download it onto my phone
... and the list goes on and on.
this kind of problem could be solved as below
(on_Prep|to_Prep|...)
But in some situations, this problem occurs with determiners such as
Eat the food
Eat food
I know the meaning of the above sentences is not exactly the same but is there any way to accomplish such a goal?
I tried the following but it seemed unlogical.
mkNP
(the_Det|)
(mkN ("food"))
I also tried to add an empty string for determiner such as mkDet (mkDigits (""))
but unfortunately, the above two ways seem not smart enough.😁😁
Your general approach with using | is correct.
There is no empty determiner, but rather another overload instance of mkNP. There's one with a determiner (so Det -> N -> NP) and another without, just N -> NP. So you can do this:
eat_food_VP : VP =
mkVP eat_V2 (mkNP the_Det food_N | mkNP food_N) ;

Solve "Out of local stack" in this specific constraint programming in prolog

I'm currently trying to create schedules for bus drivers in prolog. I wish to find a limited number of solutions. But I get the "Out of local stack" error, and I suppose it is because I'm getting too many solutions.
How can I prevent that error given the following code? Any tips on whatever I'm not doing correctly would help immensely too.
count_drivers: counts the number of drivers with D_id as driver_id
( I need them to work less than "max_hours").
vehicle: represents the bus and respective routes.
connected: represents the connection between the relief opportunities
( a route consists of a group of relief points and the respective "connection"
between them)
workpiece: is a segment of work in the same vehicle between two relief points
spell: is a group of workpieces done by the same driver
spreadover: is the whole shift one driver has to do.
Here is the code:
?- use_module(library(clpfd)).
?- use_module(library(lists)).
?- use_module(library(aggregate)).
%workpiece(Bus,[Ro1,Ro2],Weight).
workpiece(1,[1,2],1).
workpiece(1,[2,3],2).
workpiece(1,[3,4],1).
workpiece(1,[4,5],2).
workpiece(1,[5,6],1).
workpiece(2,[7,8],2).
workpiece(2,[8,9],2).
workpiece(2,[9,10],1).
workpiece(2,[10,11],2).
workpiece(2,[11,12],1).
workpiece(3,[13,14],2).
workpiece(3,[14,15],1).
workpiece(3,[15,16],2).
workpiece(3,[16,17],1).
workpiece(3,[17,18],2).
%spell
spell(Vehicle,[[Ro1,Ro2]|Tail]):-Vars = [Ro1,Ro2], Vars in 1..18, workpiece(Vehicle,[Ro1,Ro2],_),spell(Vehicle,Tail,Ro2),labeling([],Vars).
spell(_,[],_).
spell(Vehicle,[[Ro1,Ro2]|Tail],Ro3):- Vars = [Ro3], Vars in 1..18, Ro3 #= Ro1, workpiece(Vehicle,[Ro1,Ro2],_),spell(Vehicle,Tail,Ro2), labeling([],Vars).
%spreadover de cada driver
spreadover(_,List):- Vars = I, Vars in 1..15, length(List,I), I #>= 1.
spreadover(Driver,[Head|Tail]):- Vars = [Vehicle,I], Vars in 1..9, Vehicle #>= 1, Vehicle #=< 3, spell(Vehicle,Head), length(Head,I), I #>= 1, spreadover(Driver,Tail), labeling([],Vars).
%ocupar as workpieces todas
%minimizando os shifts
%cobrir todas as routes
%length 15
%drivershifts
drivershifts(_,List):- Vars = I, Vars in 1..15, length(List,I), I #= 15.
drivershifts(NumDrivers,[[Driver|List]|Tail]):-Vars = Driver, Vars in 1..NumDrivers, Driver #>= 1, Driver #=< NumDrivers, spreadover(Driver,List), labeling([],Vars).
I thank you all in advance for any time you can spare in helping me.
EDIT: I changed the code around a bit, now I get a load of unassigned variables from a query of
forall(spreadover(1,List),writeln(List)).
or one unassigned variable from
spreadover(1,List).
I restricted the domains wherever I could, but aren't sure if I'm doing this correctly.
From the queries above I should generate spreadovers(a set of spells) for driver 1.
Not sure if I should post a new question or rewrite this one either, so decided to rewrite this one.
You have many warnings from Singleton variables, and would be good style to solve them.
At least, prefix variables you know are unused with an underscore, to avoid the warning.
Now to the loop: you're calling diagram with a free variable, causing an infinite recursion that 'construct' an infinite list of partially instantiated variables.
I can't understand what could be the intended meaning of diagram/1. For sure, you miss the base case: add something like
diagram([]).

OData $filter with items in a $expand

I have given some web services to access informations.
The first thing that i have tries to expand a node . And i have done that successfully with following code
http://www.domain.com/ODataService/WorkService.svc/CaseStudies?format=json&$expand=ServiceOfferings
Now i want to filter ServiceOfferingID that i will get when expanding ServiceOfferings .
How can use filter option against a expanded collection
http://www.domain.com/ODataService/WorkService.svc/CaseStudies?format=json&$expand=ServiceOfferings&$filter=ServiceOfferings.ServiceOfferingID eq 127
But its not working. What is right way to do the same
The query you'll need to write depends on the cardinality of the expanded collection.
Here are some examples that use the public sample OData Northwind service, provided by odata.org.
An order is always done by exactly one customer.
Find the orders made by a customer with a specific name:
http://services.odata.org/V3/Northwind/Northwind.svc/Orders?$expand=Customer&$filter=Customer/CompanyName eq 'Vins et alcools Chevalier'. This is equivalent to the answer of Dhawal.
A customer can issue many orders.
Use the quantifiers all or any to specify whether you want at least one, or all of the orders to obey your conditions.
Find customers for which one or more orders have been processed by a specific employee:
http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/any(o: o/EmployeeID eq 9)
Find customers that haven't ordered anything for a long time:
http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/all(o: o/OrderDate lt DateTime'1997-01-01')
You can call http://services.odata.org/V3/Northwind/Northwind.svc/$metadata and inspect the NavigationProperty elements, to see which relations exist.
<NavigationProperty Name="Orders"
Relationship="NorthwindModel.FK_Orders_Customers"
ToRole="Orders"
FromRole="Customers"/>
Then, look for an association with that name and you'll find the cardinality:
<Association Name="FK_Orders_Customers">
<End
Type="NorthwindModel.Customer"
Role="Customers"
Multiplicity="0..1"/>
<End
Type="NorthwindModel.Order"
Role="Orders"
Multiplicity="*"/>
...
Navigating a one-to-many relationship like this: http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/EmployeeID eq 9, will give you: "The parent value for a property access of a property 'EmployeeID' is not a single value. Property access can only be applied to a single value."
Navigating a many-to-one relationship with all or any, like http://services.odata.org/V3/Northwind/Northwind.svc/Orders?$expand=Customer&$filter=Customer/any(c: c/CompanyName eq 'Vins et alcools Chevalier'), will give you:
"Any/All may only be used following a collection."
By the way, all() and any() are actually the Universal quantifier, ∀() and the existential quantifier, ∃(), respectively, which you may remember from math class.
Filtering by child object's properties is supported in oData.
Here is an example:
http://services.odata.org/Northwind/Northwind.svc/Orders?$filter=Customer/Country eq 'Germany'
Might be helpful for someone
GET serviceRoot/People?$expand=Trips($filter=Name eq 'Trip in US')
In OData the Filter command only works on the top level element. For your filter to work you would need to have the following URL
http://www.example.com/ODataService/WorkService.svc/CaseStudies(x)/ServiceOfferings?format=json&$filter=ServiceOfferingID eq 127
Obviously this isn't the query you are trying to write, but behind the scenes your query is being converted to an expression tree which has a root expression based on the top level element.
If you really required to filter the data you could potentially intercept the query and write your own expression as below:
[QueryInterceptor("CaseStudies")]
public Expression<Func<CaseStudie, bool>> CaseStudieFilter()
{
<Expression here>
}
You can also accomplish this through a webget on the service. I have had to do something similar to filter by properties of properties.