I have several complex rules that fail when confronted by ambiguous concepts:
Here's a simple example:
ANNOTATIONLIST temp;
DECLARE TestPerson(uima.tcas.Annotation concept);
DECLARE TestPlace(uima.tcas.Annotation concept);
DECLARE TestSubject(uima.tcas.Annotation concept, uima.cas.FSArray children, String kind);
DECLARE TestModifier(uima.tcas.Annotation concept);
DECLARE TestBE;
DECLARE TestAdj;
"bank" -> TestPerson;
"bank" -> TestPlace;
"nice" -> TestAdj;
"was" -> TestBE;
p:TestPlace{-> CREATE(TestSubject,"concept"=p, "children"=p, "kind"="place")};
p:TestPerson{-> CREATE(TestSubject,"concept"=p, "children"=p, "kind"="person")};
a:TestAdj{-> CREATE(TestModifier,"concept"=a)};
DECLARE TestRelation (uima.tcas.Annotation arg1 ,uima.tcas.Annotation arg2,String kind);
(p:TestSubject TestBE? m:TestModifier)
{ ->
child:CREATE(TestRelation, "kind"="BE", "arg1"=p.concept, "arg2"=m.concept),
LOG("child1:" + m.ct),
LOG("parent1:" + p.ct),
ASSIGN(temp, p.children), // what we're stuck with
ADD(temp, child),
FILL(TestSubject, "children"=temp)
};
For the input sentence "The bank was nice". only ONE of the bank meanings gets 2 children:
<RutaMain:TestPerson xmi:id="2555" sofa="37" begin="4" end="8"/>
<RutaMain:TestPlace xmi:id="2560" sofa="37" begin="4" end="8"/>
<RutaMain:TestAdj xmi:id="2565" sofa="37" begin="13" end="17"/>
<RutaMain:TestBE xmi:id="2569" sofa="37" begin="9" end="12"/>
<RutaMain:TestSubject xmi:id="2577" sofa="37" begin="4" end="8" concept="2560" children="2555 2657" kind="place"/>
<RutaMain:TestSubject xmi:id="2591" sofa="37" begin="4" end="8" concept="2555" children="2555" kind="person"/>
<RutaMain:TestModifier xmi:id="2605" sofa="37" begin="13" end="17" concept="2565"/>
<RutaMain:TestRelation xmi:id="2622" sofa="37" begin="4" end="17" arg1="2560" arg2="2565" kind="BE"/>
<RutaMain:TestRelation xmi:id="2657" sofa="37" begin="4" end="17" arg1="2555" arg2="2565" kind="BE"/>
I am using Ruta 2.7.0 but the problems with ambiguity are worse with 2.8.1 (in other cases)
I strongly recommend upgrading to Ruta 3.2.0
(p:TestSubject TestBE? m:TestModifier)
{ -> child:CREATE(TestRelation, "kind"="BE", "arg1"=p.concept, "arg2"=m.concept),
ASSIGN(temp, p.children),
ADD(temp, child),
p.children=temp
};
In your rule, FILL(TestSubject, "children"=temp) matches on the first TestSubject at this position in the index, but not that one matched by the rule element before.
(I tested the rule with the current Ruta version)
Related
Is there a standard way to determine what features are available for a given crate?
I'm trying to read Postgres timezones, and this says to use the crate postgres = "0.17.0-alpha.1" crate's with-time or with-chrono features.
When I try this in my Cargo.toml:
[dependencies]
postgres = { version = "0.17.0-alpha.1", features = ["with-time"] }
I get this error:
error: failed to select a version for `postgres`.
... required by package `mypackage v0.1.0 (/Users/me/repos/mypackage)`
versions that meet the requirements `^0.17.0-alpha.1` are: 0.17.0, 0.17.0-alpha.2, 0.17.0-alpha.1
the package `mypackage` depends on `postgres`, with features: `with-time` but `postgres` does not have these features.
Furthermore, the crate page for postgres 0.17.0 says nothing about these features, so I don't even know if they're supposed to be supported or not.
It seems like there would be something on docs.rs about it?
Crates uploaded to crates.io (and thus to docs.rs) will show what feature flags exist. crates.io issue #465 suggests placing the feature list on the crate's page as well.
Beyond that, the only guaranteed way to see what features are available is to look at the Cargo.toml for the crate. This generally means that you need to navigate to the project's repository, find the correct file for the version you are interested in, and read it.
You are primarily looking for the [features] section, but also for any dependencies that are marked as optional = true, as optional dependencies count as an implicit feature flag.
Unfortunately, there's no requirement that the crate author puts any documentation about what each feature flag does. Good crates will document their feature flags in one or more locations:
As comments in Cargo.toml
Their README
Their documentation
See also:
How do you enable a Rust "crate feature"?
For the postgres crate, we can start at crates.io, then click "repository" to go to the repository. We then find the right tag (postgres-v0.17.0), then read the Cargo.toml:
[features]
with-bit-vec-0_6 = ["tokio-postgres/with-bit-vec-0_6"]
with-chrono-0_4 = ["tokio-postgres/with-chrono-0_4"]
with-eui48-0_4 = ["tokio-postgres/with-eui48-0_4"]
with-geo-types-0_4 = ["tokio-postgres/with-geo-types-0_4"]
with-serde_json-1 = ["tokio-postgres/with-serde_json-1"]
with-uuid-0_8 = ["tokio-postgres/with-uuid-0_8"]
You can use the cargo-feature crate to view and manage your dependencies' features:
> cargo install cargo-feature --locked
> cargo feature postgres
Avaliable features for `postgres`
array-impls = ["tokio-postgres/array-impls"]
with-bit-vec-0_6 = ["tokio-postgres/with-bit-vec-0_6"]
with-chrono-0_4 = ["tokio-postgres/with-chrono-0_4"]
with-eui48-0_4 = ["tokio-postgres/with-eui48-0_4"]
with-eui48-1 = ["tokio-postgres/with-eui48-1"]
with-geo-types-0_6 = ["tokio-postgres/with-geo-types-0_6"]
with-geo-types-0_7 = ["tokio-postgres/with-geo-types-0_7"]
with-serde_json-1 = ["tokio-postgres/with-serde_json-1"]
with-smol_str-01 = ["tokio-postgres/with-smol_str-01"]
with-time-0_2 = ["tokio-postgres/with-time-0_2"]
with-time-0_3 = ["tokio-postgres/with-time-0_3"]
with-uuid-0_8 = ["tokio-postgres/with-uuid-0_8"]
with-uuid-1 = ["tokio-postgres/with-uuid-1"]
Note: this only works if the crate is already in Cargo.toml as a dependency.
The list of features are also displayed when using cargo add:
> cargo add postgres
Updating crates.io index
Adding postgres v0.19.4 to dependencies.
Features:
- array-impls
- with-bit-vec-0_6
- with-chrono-0_4
- with-eui48-0_4
- with-eui48-1
- with-geo-types-0_6
- with-geo-types-0_7
- with-serde_json-1
- with-smol_str-01
- with-time-0_2
- with-time-0_3
- with-uuid-0_8
- with-uuid-1
It seems like there would be something on docs.rs about it?
Other people thought so too! This was added to docs.rs in late 2020. You can view the list of features from the crate's documentation by navigating to "Feature flags" on the top bar:
You still won't see the list of features of postgres 0.17.0 though since old documentation isn't regenerated when new functionality is added to the site, but any recently published versions will have it available.
Note: this is only available on docs.rs and not generated when running cargo doc.
The feature-set of a dependency can be retrieved programmatically via the cargo-metadata crate:
use cargo_metadata::MetadataCommand;
fn main() {
let metadata = MetadataCommand::new()
.exec()
.expect("failed to get metadata");
let dependency = metadata.packages
.iter()
.find(|package| package.name == "postgres")
.expect("failed to find dependency");
println!("{:#?}", dependency.features);
}
{
"with-time-0_3": [
"tokio-postgres/with-time-0_3",
],
"with-smol_str-01": [
"tokio-postgres/with-smol_str-01",
],
"with-chrono-0_4": [
"tokio-postgres/with-chrono-0_4",
],
"with-uuid-0_8": [
"tokio-postgres/with-uuid-0_8",
],
"with-uuid-1": [
"tokio-postgres/with-uuid-1",
],
"array-impls": [
"tokio-postgres/array-impls",
],
"with-eui48-1": [
"tokio-postgres/with-eui48-1",
],
"with-bit-vec-0_6": [
"tokio-postgres/with-bit-vec-0_6",
],
"with-geo-types-0_6": [
"tokio-postgres/with-geo-types-0_6",
],
"with-geo-types-0_7": [
"tokio-postgres/with-geo-types-0_7",
],
"with-eui48-0_4": [
"tokio-postgres/with-eui48-0_4",
],
"with-serde_json-1": [
"tokio-postgres/with-serde_json-1",
],
"with-time-0_2": [
"tokio-postgres/with-time-0_2",
],
}
This is how other tools like cargo add and cargo feature provide dependency and feature information.
How can I do a function to get the current year with 4 digits using ELM 0.19.1? I have read something but nothing works with 0.19.1.
Signature:
getCurrentYear : Int
Execution:
getCurrentYear => 2020
Edit:
Maybe executing new Date().getFullYear() javascript code?
The simplest way would be to pass the year in via flags when you start the app, since the current year isn't likely to change in the course of the application running. In that case, you can use the snippet of JavaScript you suggested (ellie example):
Elm.Main.init({
node: document.querySelector('main'),
flags: {
year: new Date().getFullYear(),
}
});
module Main exposing (main)
import Browser
import Html exposing (Html, p, text)
type alias Flags =
{ year : Int }
main : Program Flags Model Msg
main =
Browser.element
{ init = \flags -> ( Model flags.year, Cmd.none )
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
type alias Model =
{ year : Int }
type Msg
= NoOp
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
view : Model -> Html Msg
view model =
p [] [ text "The year is ", text (String.fromInt model.year) ]
Alternatively, you can use Time.now to request the current time, as Robin Zigmond's answer suggests, however that is pointing to Elm 0.18 documentation (for elm-lang/core instead of elm/time). For 0.19, you need both a Time.Posix and a Time.Zone in order to call Time.toYear. You can chain Time.now (a Task producing a Posix value) and Time.here (a Task producing a Zone with the current time zone offset) to retrieve those values in one Cmd. Here's an example (also on ellie)
module Main exposing (main)
import Browser
import Html exposing (Html, p, text)
import Task exposing (Task)
import Time
type alias Flags =
{ year : Int }
main : Program () Model Msg
main =
Browser.element
{ init = \() -> ( Model 0, whatYearIsIt |> Task.perform GotYear )
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
whatYearIsIt : Task x Int
whatYearIsIt =
Task.map2 Time.toYear Time.here Time.now
type alias Model =
{ year : Int }
type Msg
= GotYear Int
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
GotYear year ->
( { model | year = year }, Cmd.none )
view : Model -> Html Msg
view model =
p [] [ text "The year is ", text (String.fromInt model.year) ]
As I already said in my comment, it's impossible to define a function in Elm that returns the current year. You have to get such information from the Elm runtime system (which is basically JavaScript, but you don't have to write it yourself). This happens via commands, where you tell the runtime system to do something for you. But note that you can't simply retrieve the "return value" of that command and get it back into your Elm code. Instead you have to pass it into a function that can convert it into a "message" (see basic Elm Architecture tutorial here, it's fundamental to understand this before you can do anything with Elm) - this then allows you to store the value in your Model and thereby display it in your app.
These patterns do take some getting your head around, especially if you're not used to pure functional programming - but once you get used to it the benefits are huge, including a near guaranteed absence of runtime errors, and greatly enhanced ability to reason about your code.
For getting the year specifically, it looks like you need this library, which gives you (as now) a Task rather than a Cmd. You can use Task.perform to convert it to a command, which is documented here - in fact it even gives an example that matches your use case quite closely - I'll copy it here for posterity:
import Time -- elm install elm/time
import Task
type Msg
= Click
| Search String
| NewTime Time.Posix
getNewTime : Cmd Msg
getNewTime =
Task.perform NewTime Time.now
You'll have to fill this in to fit your own use case, in particular your own Msg type. But it gives a good basic outline. To get the user's current year, you need to replace the Time.Posix type with Int, and the Time.now command with (Task.map2 Time.toYear Time.here Time.now), as explained by #bdukes in his answer.
How to get data below/above annotated keyword present in other line? I am able to annotate keyword but not able to get information
Sample text:
Underwriter's Name Appraiser's Name Appraisal Company Name
Alice Wheaton Cooper Bruce Banner Stark Industries
Code
TYPESYSTEM utils.PlainTextTypeSystem;
ENGINE utils.PlainTextAnnotator;
EXEC(PlainTextAnnotator, {Line});
ADDRETAINTYPE(WS);
Line{->TRIM(WS)};
REMOVERETAINTYPE(WS);
Document{->FILTERTYPE(SPECIAL)};
DECLARE UnderWriterKeyword, NameKeyword, UnderWriterNameKeyword;
DECLARE UnderWriterName(String label, String value);
CW{REGEXP("\\bUnderwriter") -> UnderWriterKeyword};
CW{REGEXP("Name")->NameKeyword};
(UnderWriterKeyword SW NameKeyword){->UnderWriterNameKeyword};
ADDRETAINTYPE(SPACE);
Line{CONTAINS(UnderWriterNameKeyword)} Line -> {
(CW SPACE)+ {-> MARK(UnderWriterName)};
};
REMOVERETAINTYPE(SPACE)
Expected Output :
Underwriter's Name: Alice Wheaton Cooper
Appraiser's Name: Bruce Banner
Appraisal Company Name: Stark Industries
Please suggest if it is possible in RUTA ? If true, how to get data?
TYPESYSTEM utils.PlainTextTypeSystem;
ENGINE utils.PlainTextAnnotator;
DECLARE Header;
DECLARE ColumnDelimiter;
DECLARE Cell(INT column);
DECLARE Keyword (STRING label);
DECLARE Keyword UnderWriterNameKeyword, AppraiserNameLicenseKeyword,
AppraisalCompanyNameKeyword;
"Underwriter's Name" -> UnderWriterNameKeyword ( "label" = "UnderWriter
Name");
"Appraiser's Name/License" -> AppraiserNameLicenseKeyword ( "label" =
"Appraiser Name");
"Appraisal Company Name" -> AppraisalCompanyNameKeyword ( "label" =
"Appraisal Company Name");
DECLARE Entry(Keyword keyword);
EXEC(PlainTextAnnotator, {Line,Paragraph});
ADDRETAINTYPE(WS);
Line{->TRIM(WS)};
Paragraph{->TRIM(WS)};
SPACE[3,100]{-PARTOF(ColumnDelimiter) -> ColumnDelimiter};
Line -> {ANY+{-PARTOF(Cell),-PARTOF(ColumnDelimiter) -> Cell};};
REMOVERETAINTYPE(WS);
INT index = 0;
BLOCK(structure) Line{}{
ASSIGN(index, 0);
Line{STARTSWITH(Paragraph) -> Header};
c:Cell{-> c.column = index, index = index + 1};
}
Header<-{hc:Cell{hc.column == c.column}<-{k:Keyword;};}
# c:#Cell{-PARTOF(Header) -> e:Entry, e.keyword = k};
DECLARE Entity (STRING label, STRING value);
DECLARE Entity UnderWriterName, AppraiserNameLicense, AppraisalCompanyName;
FOREACH(entry) Entry{}{
entry{ -> CREATE(UnderWriterName, "label" = k.label, "value" =
entry.ct)}<-{k:entry.keyword{PARTOF(UnderWriterNameKeyword)};};
entry{ -> CREATE(AppraiserNameLicense, "label" = k.label, "value" =
entry.ct)}<-{k:entry.keyword{PARTOF(AppraiserNameLicenseKeyword)};};
entry{ -> CREATE(AppraisalCompanyName, "label" = k.label, "value" =
entry.ct)}<-{k:entry.keyword{PARTOF(AppraisalCompanyNameKeyword)};};
}
The most important rule is the following:
Header<-{hc:Cell{hc.column == c.column}<-{k:Keyword;};}
# c:#Cell{-PARTOF(Header) -> e:Entry, e.keyword = k};
It contains three rule element, Header,# and Cell, and works this way:
The rule starts to match with the Cell rule element because it is tagged as anchor with #.
This rule element matches on all Cell annotations that or not part of a Header annotation. It starts with the first Cell annotation that fulfills this condition and calls it "c".
The next rule element is # which matches until the next rule element is able to match.
The next rule element matches on a Header annotation if the inlined rule is able to match within the span of the Header annotation. The inlined rule matches on the Cell annotations remembered as "hc" within this span that have the same value for the feature column. The match is successful, if it contains a Keyword remembered as "k".
If these three rule elements matched successfully, then the actions are applied.
The first action creates an Entry annotation called "e" on the span of the Cell annotation.
The second action assigns the keyword to the Entry feature keyword.
As a summary, the rule creates an Entry annotation for each Cell annotation that is not part of the header and assigns the header keyword of the corresponding column in order to define the type of the entry.
Take a look at inlined rules in Ruta.
You could define your condition for one line and annotate the needed info inside the next one:
Line{CONTAINS(UserName)} Line -> { //your logic here };
Given:
class Point {
int x;
int y;
}
List<Point> points;
How can I check that property x in a list of Points is greather than a value? I aim something similar to:
assertThat(points).extracting("x").isGreatherThan(20)
However I can't find 'isGreatherThan' after 'extracting'
Update
I don't aim writing custom conditions for this kind of value checking, as assertj already has methods for checking numbers.
Thanks
You can use filteredOn as it supports java 8 Predicate, e.g:
assertThat(listOfPoints).filteredOn(p -> p.x > 20).isNotEmpty();
If you want to do more complex stuff, using Condition is the way to go, in AssertJ 3.x they are simpler to write, rewriting Florian Schaetz example:
Condition<Integer> greaterThan20 = new Condition<>(v -> v.intValue() > 20, "greater than 20");
You can try this one...
.extracting( "x", Integer.class ).areAtLeast( 1, greaterThan20 );
Of course you'll have to write the condition yourself, something like...
final Condition<Integer> greaterThan20 = new Condition<Integer>("greater than 20") {
#Override
public boolean matches(Integer value) {
return value.intValue() > 20;
}
};
In Java 8 you can do something like this:
assertThat(listOfPoints.stream().filter(p->p.x > 20).toArray()).hasSameSizeAs(listOfPoints);
That's for the case where you want ALL points to have x > 20.
To verify that there's at least one (as in Florian Schaetz's answer):
assertThat(listOfPoints.stream().filter(p->p.x > 20).toArray()).isNotEmpty();
I'm trying to upgrade a DB in an app for Ubuntu Touch. I use QtQuick.LocalStorage 2.0.
When I call db.changeVersion it works, but db.version doesn't change until app restarts.
db.changeVersion(db.version, "2", function(tx){...}); // Update database to version 2
console.log(db.version); //Should return "2", instead returns previous version of database
How can have the new db.version without restart the app?
This has been recently fixed in Qt. The changeVersion function will now return a new db object which has the version field updated.
https://bugreports.qt.io/browse/QTBUG-71838
Previous Qt versions required the user to reopen the database to see the updated version, as evidenced by the test code:
http://code.qt.io/cgit/qt/qtdeclarative.git/tree/tests/auto/qml/qqmlsqldatabase/data/changeversion.js
This bug has been fixed, see Andrzej's answer
ORIGINAL ANSWER
I resolved my problem writing this function, that permits to upgrade from any version of the DB to the last version without problems.
/* We need this function because db.version is in the .ini file, that is update only by Javascript Garbage Collection.
* So, we have to upgrade from actual version to the last version using only once db.changeVersion.
* To avoid to have a lot of switch and spaghetti-code, this function allow to add new db version without modify old sql
*
* IMPORTANT: NUMBER OF VERSION HAVE TO BE INT (e.g. 0.1, not 0.1.1)
*/
function upgradeDB() {
// This is the array with all the sql code, insert your update at the last
var sqlcode = [
'CREATE TABLE IF NOT EXISTS Calculations(id INTEGER PRIMARY KEY, calc TEXT)',
'ALTER TABLE Calculations ADD insertDate INTEGER NOT NULL DEFAULT 0'
]
// This is the last version of the DB, remember to update when you insert a new version
var lastVersion = "0.2";
// Hack for change old numeration with new one
if (db.version == "0.1.1") {
db.changeVersion("0.1.1", "0.2");
console.log("Fixed DB!");
}
// So, let's start the version change...
db.changeVersion(db.version, lastVersion,
function(tx) {
if (db.version < 0.1) {
tx.executeSql(sqlcode[0]);
console.log('Database upgraded to 0.1');
}
if (db.version < 0.2) {
tx.executeSql(sqlcode[1]);
console.log('Database upgraded to 0.2');
}
/* This is the structure of the update:
* n is the number of version that sql update to
* m is the number of the sql element in the array. Remember that the number of the first element of array is 0 ;)
if (db.version < n) {
tx.executeSql(sqlcode[m]);
console.log('Database upgraded to n');
}
*/
}); // Finish db.changeVersion
}