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 !
Related
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?
The invert method for Lists should return the inverted sequence, or at least that's what the source seems to imply. However:
say (1,3,2).invert
fails with:
(exit code 1) Type check failed in invert; expected Pair but got Int (1) in block <unit>
The documentation does not help, because it's LTA in this area (and missing for List). But the source code does not admit any ambiguous interpretation. Is there anything I'm missing here?
Perhaps you intended to use the reverse method. Well, if you want the result to be (2,3,1).
It looks like the documentation of List.invert is indeed missing. It is intended to work only on a List that consists of Pairs. I'll write that up now.
EDIT: doc added with https://github.com/perl6/doc/commit/0ee3245776
In Perl6, operators subroutines and methods have a singular purpose for a given name.
In the case of the infix + operator it is to add two numbers. So if it is given something that is not a number it tries to turn it into a number before adding.
In the case of the .invert method, its fundamental purpose is to invert a Pair object. That is swap the .key and the .value of a Pair.
So everywhere that .invert can be used, it does so in the way that is most like inverting a Pair object.
On a Pair object with a singular .value, it swaps the key and the value.
say ('a' => 'A').invert;
# (A => a)
If the .value is not singular it gives you a sequence where each value is now the key of its own Pair.
say ('a' => ('A', 'B')).invert;
# (A => a B => a)
Note that .invert always returns a sequence to be consistent. Even on that first example.
On a Hash it does it on all of the key / value pairs.
say %( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).invert.sort;
# (A => 1 A => a B => a B => b)
On a List, it could do it one of two ways.
It could use the index as the key, exactly like .antipairs does.
say ( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).antipairs.sort;
# ((1 => A) => 2 (a => (A B)) => 0 (b => B) => 1)
say ( 'a', 'b', 'c' ).antipairs;
# (a => 0 b => 1 c => 2)
It could go through each of the Pairs in the list like it currently does.
say ( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).invert.sort
(A => 1 A => a B => a B => b)
Since .antipairs already works like .pairs except the opposite, there is really no reason for .invert to also work like it. That would have also made .invert less like a Pair method.
This also has the nice effect that you can get the Pairs from a Hash as a list then call .invert on it, and it will work like just calling .invert on the Hash directly.
say %( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).invert.sort;
# (A => 1 A => a B => a B => b)
say %( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).list.invert.sort;
# (A => 1 A => a B => a B => b)
It also means that you can call .invert several times and it stays consistent.
say %( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).invert.invert.invert.sort;
# (A => 1 A => a B => a B => b)
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>();
I'm using NHibernate 3.0 with both the LINQ provider and QueryOver. Sometimes I want to eager load related data, and there comes the method "Fetch" to the rescue, both in LINQ and QueryOver. Now I have a special scenario where I want to eager load a property not directly on the second level, like:
Foo f = ...;
f.A.B.C
with LINQ there's no problem, as you can "chain" fetches with the method "ThenFetch", like:
var result = Session.Query<Foo>().Fetch(a => a.A).ThenFetch(b => b.B).ThenFetch(c => c.C).ToList();
In QueryOver there's no such method, so how can I achieve the same result?
Thanks in advance.
I actually managed to solve this problem using two different approaches:
Approach one:
Session.QueryOver<Foo>().Fetch(x => x.A).Fetch(x => x.A.B).Fetch(x => x.A.B.C)
Approach two:
A a = null;
B b = null;
C c = null;
Session.QueryOver<Foo>()
.JoinAlias(x => x.A, () => a)
.JoinAlias(() => a.B, () => b)
.JoinAlias(() => b.C, () => c)
Both work (altough I'm not exactly sure if one of them generated "inner" and the other one "outer" joins).
Just as a curiosity, I'll post the reply they gave me on the NHibernate Jira:
query
.Fetch(p => p.B)
.Fetch(p => p.B.C) // if B is not a collection ... or
.Fetch(p => p.B[0].C) // if B is a collection ... or
.Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method)
I think you can do that with JoinQueryOver
IQueryOver<Relation> actual =
CreateTestQueryOver<Relation>()
.Inner.JoinQueryOver(r => r.Related1)
.Left.JoinQueryOver(r => r.Related2)
.Right.JoinQueryOver(r => r.Related3)
.Full.JoinQueryOver(r => r.Related4)
.JoinQueryOver(r => r.Collection1, () => collection1Alias)
.Left.JoinQueryOver(r => r.Collection2, () => collection2Alias)
.Right.JoinQueryOver(r => r.Collection3)
.Full.JoinQueryOver(r => r.People, () => personAlias);
I'm trying to load all the collections eagerly, using NHibernate 3 alpha 1. I'm wondering if this the right way of using ThenFetch()?
Properties with plural names are collections. The others are just a single object.
IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
from mi in db
where mi.RunDate == runDate
select mi).Fetch(mi => mi.Milestone)
.ThenFetch(m => m.PrimaryOwners)
.Fetch(mi => mi.Milestone)
.ThenFetch(m => m.SecondaryOwners)
.Fetch(mi => mi.Milestone)
.ThenFetch(m => m.Predecessors)
.Fetch(mi => mi.Milestone)
.ThenFetch(m => m.Function)
.Fetch(mi => mi.Milestone)
.ThenFetchMany(m => m.Jobs)
.ThenFetch(j => j.Source)
;
I thought of asking this in the NHibernate forums but unfortunately access to google groups is forbidden from where I am. I know Fabio is here, so maybe the guys from the NHibernate team can shed some light on this?
Thanks
Apparently, there's no "right" way to use ThenFetch in such a case. Your example works fine but SQL produced contains many joins to Milestone, which isn't that right.
Using IQueryOver instead of IQueryable allows you to use complex syntax in Fetch:
Fetch(p => p.B)
Fetch(p => p.B.C) // if B is not a collection ... or
Fetch(p => p.B[0].C) // if B is a collection ... or
Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method)
So in your case it would be:
query // = session.QueryOver<X>()
.Fetch(mi => mi.Milestone).Eager
.Fetch(mi => mi.Milestone.PrimaryOwners).Eager
.Fetch(mi => mi.Milestone.SecondaryOwners).Eager
.Fetch(mi => mi.Milestone.Predecessors).Eager
.Fetch(mi => mi.Milestone.Function).Eager
.Fetch(mi => mi.Milestone.Jobs).Eager
.Fetch(mi => mi.Milestone.Jobs.First().Source).Eager
The one thing you are missing is that you should use FetchMany() and ThenFetchMany() is the child property is a collection.
IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
from mi in db
where mi.RunDate == runDate
select mi);
var fetch = milestoneInstances.Fetch(f => f.Milestone);
fetch.ThenFetch(f => f.PrimaryOwners);
fetch.ThenFetch(f => f.SecondaryOwners);
//...
As leora said, make sure when fetching children collections that you use
FetchMany()
ThenFetchMany()
A new Fetch, should pick up from the root, but this does not always happen. Sometimes you need to create them as separate queries or use Criteria Futures to batch up a multiple fetch.