shade-ai / daidepp Goto Github PK
View Code? Open in Web Editor NEWRepo to store universal communication specification
Repo to store universal communication specification
There are two visit_prov_coast methods in the DAIDEVisitor
class. One needs to be removed.
This would allow generating DAIDE messages like this: https://www.nltk.org/howto/generate.html
Broken link is here:
The machine-parsable grammar can be found in this .py file
Now that we've hit version 1.0.0
, the output is fundamentally different (i.e. much better!). This should be reflected in the README.
Can use this workflow.
What functionality will your new tokens add?
A new token might be added for sending potential/indeterminate acceptance responses to an order proposal.
Describe the precise changes you'd like
Additional context
For the negotiation between agents, we are proposing Daide extension.
from daidepp import create_daide_grammar, daide_visitor
grammar = create_daide_grammar(level=130)
message = <MESSAGE>
parse_tree = grammar.parse(message)
output = daide_visitor.visit(parse_tree)
print(output)
When message is PRP (ALY (FRA ENG) VSS (GER RUS))
the visitor works
However, when message isPRP (ALY (FRA ENG) VSS (GER))
i.e. when only 1 country is preceded by VSS,
it raises parsimonious.exceptions.ParseError: Rule 'ws' didn't match at '))' (line 1, column 28).
What functionality will your new tokens add?
Currently, the DAIDE grammar level 8000 proposes "Free Text Press" where any power can communicate with any ASCII characters. "Freer Text Press" proposes natural language communicate using any Unicode characters. I suggest UTF-8 encodings to start with.
Describe the precise changes you'd like
Add this to daide-specification.md
:
## Level 8010: Freer Text Press
This level allows natural language press. Both message and reply can be any string of UTF-8 encoded Unicode characters.
Additional context
This is 100% serious.
I am from SHADE and would like to use this library as our main parser. We are currently using this library: https://github.com/trigaten/DAIDE, which provides simple parsing, as well as DAIDE message construction using DAIDE keywords, like the following:
# easily compose DAIDE keywords
>>> from DAIDE import Order, Unit, ORR, HLD
>>> arrangement = ORR([Order(Unit("FFF FFF FFF"), HLD()), Order(Unit("FFF FFF FFF"), HLD())])
>>> str(arrangement)
'ORR ((FFF FFF FFF) HLD) ((FFF FFF FFF) HLD)'
It would be very useful if your parser provided this support. How difficult would this be to add?
Is this a mistake? According to the markdown documentation the token should be ROF.
We would like to be able to parse ANY DAIDE string, not just messages. This means that a grammar object should be able to parse a message, arrangement, order, unit, or any other string which represents a coherent component in DAIDE.
What functionality will your new tokens add?
By providing optional tonal modifiers to DAIDE statements DAIDE can be made more expressive and closer aligned to human language. Invariably in real negotiations, tone is conveyed either mechanistically through verbal intonation, through word selection, or a combination of the two. The proposed modifiers support the latter.
Describe the precise changes you'd like
Currently we support the following tones:
Objective
Hostile
Friendly
Fearful
Confident
Empathetic
Upset
In our version of the game engine these are not treated as additional tokens in DAIDE but rather external modifiers. For example:
FRM (AUS) (ENG) (PRP (XDO ((ENG FLT LON) MTO WAL)))
would be modified by one of the tones. This could be embedded into DAIDE itself:
HOSTILE: FRM (AUS) (ENG) (PRP (XDO ((ENG FLT LON) MTO WAL)))
or
CONFIDENT: FRM (AUS) (ENG) (PRP (XDO ((ENG FLT LON) MTO WAL)))
or these tones could be treated separately altogether.
Additional context
From Jataware's standpoint tones should be ignored by teams that do not wish to support them, but if others are interested in using them we should have a broader discussion about whether this should be included as an addendum to DAIDE or whether we should treat tone separately (as we do currently).
For reference, our module that converts DAIDE + tone to human language can be found here.
We should test that code, commits, docstrings, etc. follow the appropriate formatting whenever a PR is submitted.
During some of my unit test cases, I came across a DAIDE message that should be valid but cause a Parsimonious ParseError due to a hole in the support move grammar.
The message below (an order sampled from a pool of possible orders from the SHADE game engine) returns parsimonious.exceptions.ParseError: Rule 'prov_no_coast' didn't match at 'CLY))
.
PRP(XDO((ENG FLT EDI) SUP (ENG AMY LVP) MTO CLY))
Clyde (CLY) is correctly listed as a coastal province in the grammar, and the grammar only specifies 'prov_no_coast' for support move.
What functionality will your new tokens add?
Add a new arrangement that specifies utility upper/lower bound for a particular power. This is intended for use with threats to show how much cooperation benefits the receiver over the threatened punishment.
Describe the precise changes you'd like
What functionality will your new tokens add?
New tokens might be added for sending messages with trust and distrust information
We propose “Send trust message” and “Send distrust message”.
Describe the precise changes you'd like
As shown in the README:
>>> from daidepp import AND, PRP, PCE
>>> str(AND(PRP(PCE("AUS")), PRP(PCE("AUS", "ENG"))))
AND ((PRP (PCE (AUS))) (PRP (PCE (AUS ENG))) (PRP (PCE (AUS ENG FRA))))
But per the DAIDE syntax, AND
should follow this format:
arrangement = AND (arrangement) (arrangement) (arrangement) ...
This means we are adding an unnecessary left parenthesis at the beginning and an unnecessary right parenthesis at the end. The output should be this:
AND (PRP (PCE (AUS))) (PRP (PCE (AUS ENG))) (PRP (PCE (AUS ENG FRA)))
The same issue is present in ORR.
What functionality will your new tokens add?
New tokens might be added for threatening a power on certain actions.
We propose “Send break friendship threat” and “Send last offer threat”
Describe the precise changes you'd like
Additional context
For the negotiation between agents, we are proposing Daide extension.
What functionality will your new tokens add?
New tokens might be added for Return Favor Commitment and returning the favor.
Describe the precise changes you'd like
Additional context
For the negotiation between agents, we are proposing Daide extension.
The Gulf of Bothnia should be GOB, but right now it is BOT.
What functionality will your new tokens add?
A new token might be added for sending a message requesting the Best Alternative proposal against a proposal that has been received. Another new token will be needed to send the best alternative to a previously sent proposal.
Describe the precise changes you'd like
Additional context
For the negotiation between agents, we are proposing a Daide extension.
What functionality will your new tokens add?
Allow any well-formed DAIDE statement to be weighted by a real-valued probability between 0 and 1.
Describe the precise changes you'd like
For any valid DAIDE message MSG:
(PROB 0.7 MSG)
A DMZ proposal only makes sense with prov_no_coast
, since a unit occupies a province regardless of which coast it is on.
Being able to install the parser as a library via adding a setup file would make integrating the code easier.
That way, by doing something like pip3 install git+https://github.com/SHADE-AI/daidepp.git
one would be able to simply import the parser as a package.
When testing #55 I got a ValueError saying not enough things to unpack in visit_not. I fixed this error by changing visited_children[0] to visited_children without indexing. However, when i pushed that commit it failed the automated tests.
Eventually, I realized that using indexing results in ValueError when level 60 is not included in the grammar but works when level 60 is not included. I have temporarily included level 60 in my grammar to work around this issue.
Level 60 extends not to wrap queries in addition to arrangements which I believe causes this difference. It seems like daide_visitor needs some logic to detect whether level 60 is included to decide whether to index visited_children.
Arrangements like PCE ( AUS GER )
have the powers in the arrangement rendered in the order in which they were passed. This is problematic because if we compare PCE ( AUS GER )
to PCE ( GER AUS )
they will be treated as different if we're comparing their string representations. We should automatically sort powers for easy comparison.
What functionality will your new tokens add?
New tokens might be added for canceling the query request that one power has already made towards another power regarding an arrangement. We propose “Sending cancellation of query request ”.
Describe the precise changes you'd like
Additional context
For the negotiation between agents, we are proposing Daide extension.
The three letter code for certain provinces do not match between the daidepp grammar and the diplomacy game engine.
The ones I have encountered thus far are (diplomacy/daidepp):
Encountering one of the diplomacy engine version of the province names causes the parser to crash. This is slightly inconvenient as we have to do some extra translation between DAIDE and diplomacy. Translating from the diplomacy engine to DAIDE for ENG is particularly thorny because it could be referring to either the english channel or England the power.
On version 1.1.4, I get an error when attempting to parse: PRP ( AND ( XDO ( ( AUS AMY BUD ) MTO SER ) ) ( XDO ( ( AUS AMY VIE ) MTO TRI ) ) ( XDO ( ( AUS FLT TRI ) MTO ALB ) ) ( XDO ( ( ENG AMY LVP ) MTO WAL ) ) ( XDO ( ( ENG FLT EDI ) MTO NTH ) ) ( XDO ( ( ENG FLT LON ) MTO ECH ) ) )
The DAIDE that is being parsed was generated by creating DAIDEPP objects PRP, AND, XDO, etc.
from daidepp import create_daide_grammar, daide_visitor
grammar = create_daide_grammar(level=130)
print(daide_visitor.visit(grammar.parse(grammar)))
Traceback (most recent call last):
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 213, in visit
return method(node, [self.visit(n) for n in node])
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/daidepp/visitor.py", line 217, in visit_and
_, _, arrangement, _, par_arrangements = visited_children[0]
ValueError: not enough values to unpack (expected 5, got 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/jale/diplomacy/pinnacle/utils/messages/message_utils.py", line 44, in parse_str
return daide_visitor.visit(grammar.parse(filtering))
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 213, in visit
return method(node, [self.visit(n) for n in node])
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 213, in <listcomp>
return method(node, [self.visit(n) for n in node])
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 213, in visit
return method(node, [self.visit(n) for n in node])
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 213, in <listcomp>
return method(node, [self.visit(n) for n in node])
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 213, in visit
return method(node, [self.visit(n) for n in node])
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 213, in <listcomp>
return method(node, [self.visit(n) for n in node])
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 213, in visit
return method(node, [self.visit(n) for n in node])
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 213, in <listcomp>
return method(node, [self.visit(n) for n in node])
File "/home/jale/miniconda3/envs/deepmind/lib/python3.8/site-packages/parsimonious/nodes.py", line 225, in visit
raise VisitationError(exc, exc_class, node)
parsimonious.exceptions.VisitationError: ValueError: not enough values to unpack (expected 5, got 0)
Parse tree:
<Node called "and" matching "AND ( XDO ( ( AUS AMY BUD ) MTO SER ) ) ( XDO ( ( AUS AMY VIE ) MTO TRI ) ) "> <-- *** We were here. ***
<Node matching "AND">
<RegexNode called "lpar" matching " ( ">
<Node called "sub_arrangement" matching "XDO ( ( AUS AMY BUD ) MTO SER ) ">
<Node called "xdo" matching "XDO ( ( AUS AMY BUD ) MTO SER ) ">
<Node matching "XDO">
<RegexNode called "lpar" matching " ( ">
<Node called "order" matching "( AUS AMY BUD ) MTO SER">
<Node called "mto" matching "( AUS AMY BUD ) MTO SER">
<RegexNode called "lpar" matching "( ">
<Node called "unit" matching "AUS AMY BUD">
<Node called "power" matching "AUS">
<Node matching "AUS">
<RegexNode called "ws" matching " ">
<Node called "unit_type" matching "AMY">
<Node matching "AMY">
<RegexNode called "ws" matching " ">
<Node called "province" matching "BUD">
<Node called "prov_landlock" matching "BUD">
<Node matching "BUD">
<RegexNode called "rpar" matching " ) ">
<Node matching "MTO">
<RegexNode called "ws" matching " ">
<Node called "province" matching "SER">
<Node called "prov_landlock" matching "SER">
<Node matching "SER">
<RegexNode called "rpar" matching " ) ">
<RegexNode called "rpar" matching ") ">
<Node matching "( XDO ( ( AUS AMY VIE ) MTO TRI ) ) ">
<Node matching "( XDO ( ( AUS AMY VIE ) MTO TRI ) ) ">
<RegexNode called "lpar" matching "( ">
<Node called "sub_arrangement" matching "XDO ( ( AUS AMY VIE ) MTO TRI ) ">
<Node called "xdo" matching "XDO ( ( AUS AMY VIE ) MTO TRI ) ">
<Node matching "XDO">
<RegexNode called "lpar" matching " ( ">
<Node called "order" matching "( AUS AMY VIE ) MTO TRI">
<Node called "mto" matching "( AUS AMY VIE ) MTO TRI">
<RegexNode called "lpar" matching "( ">
<Node called "unit" matching "AUS AMY VIE">
<Node called "power" matching "AUS">
<Node matching "AUS">
<RegexNode called "ws" matching " ">
<Node called "unit_type" matching "AMY">
<Node matching "AMY">
<RegexNode called "ws" matching " ">
<Node called "province" matching "VIE">
<Node called "prov_landlock" matching "VIE">
<Node matching "VIE">
<RegexNode called "rpar" matching " ) ">
<Node matching "MTO">
<RegexNode called "ws" matching " ">
<Node called "province" matching "TRI">
<Node called "prov_land_sea" matching "TRI">
<Node matching "TRI">
<RegexNode called "rpar" matching " ) ">
<RegexNode called "rpar" matching ") ">
What functionality will your new tokens add?
This would subsume some of the other proposals. Any well-formed coherent DAIDE message can also have a free text explication that can convey tone, elaborate, and
Describe the precise changes you'd like
To the root non-terminal, add a free text explanation. E.g., for a request message MSG, add the explication:
(Explication "This is not a request, it is a demand" MSG)
What functionality will your new tokens add?
New tokens might be added for emotional state. We propose “Send Emotional State Message”.
Describe the precise changes you'd like
Additional context
For the negotiation between agents, we are proposing Daide extension.
What functionality will your new tokens add?
A new token might be added for requesting an offer from power or demanding an offer from power.
Describe the precise changes you'd like
Additional context
For the negotiation between agents, we are proposing Daide extension.
I tried to parse a SCD arrangement using the following code snippet:
from daidepp import create_daide_grammar, daide_visitor
grammar = create_daide_grammar(level=130, string_type='all')
message = 'SCD (FRA HOL)'
parse_tree = grammar.parse(message)
output = daide_visitor.visit(parse_tree)
print(output)
Error message is as follows:
Traceback (most recent call last):
File "C:\Users\daidepp\keywords.py", line 21, in __post_init__
_grammar.parse(str(self))
File "C:\Users\parsimonious\grammar.py", line 111, in parse
return self.default_rule.parse(text, pos=pos)
File "C:\Users\parsimonious\expressions.py", line 130, in parse
node = self.match(text, pos=pos)
File "C:\Users\parsimonious\expressions.py", line 147, in match
raise error
parsimonious.exceptions.ParseError: Rule 'supply_center' didn't match at '['HOL'] )' (line 1, column 11).
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\parsimonious\nodes.py", line 213, in visit
return method(node, [self.visit(n) for n in node])
File "C:\Users\daidepp\daide_visitor.py", line 263, in visit_scd
return SCD(*power_and_supply_centers)
File "C:\Users\daidepp\keywords.py", line 376, in __init__
self.__post_init__()
File "C:\Users\daidepp\keywords.py", line 23, in __post_init__
raise Exception("Incorrect values passed, object is not valid DAIDE")
Exception: Incorrect values passed, object is not valid DAIDE
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\Users\validation.py", line 6, in <module>
output = daide_visitor.visit(parse_tree)
File "C:\Users\parsimonious\nodes.py", line 213, in visit
return method(node, [self.visit(n) for n in node])
File "C:\Users\parsimonious\nodes.py", line 213, in <listcomp>
return method(node, [self.visit(n) for n in node])
File "C:\Users\parsimonious\nodes.py", line 225, in visit
raise VisitationError(exc, exc_class, node)
parsimonious.exceptions.VisitationError: Exception: Incorrect values passed, object is not valid DAIDE
Parse tree:
<Node called "scd" matching "SCD (FRA HOL)"> <-- *** We were here. ***
<Node matching "SCD">
<Node matching " (FRA HOL)">
<RegexNode called "lpar" matching " (">
<Node called "power" matching "FRA">
<Node matching "FRA">
<RegexNode called "ws" matching " ">
<Node called "supply_center" matching "HOL">
<Node matching "HOL">
<Node matching "">
<RegexNode called "rpar" matching ")">
SCD object can be constructed using
SCD(PowerAndSupplyCenters("FRA ", Location("HOL"))
just can't be parsed using the above snippet.
This is an edge case that may not necessarily occur, but when translating something like DMZ ( GER RUS ) ( BLA SEV (STP NCS) )
, the parser throws a ParseError due to Rule prov_no_coast' didn't match at '(STP NCS) )
.
The agents may not be negotiating about making a coast a DMZ specifically for fleets since that seems sort of nonsensical, but the error is there.
>>> grammar = dpp.create_grammar_from_press_keywords(
[
"PRP",
"PCE",
"ALY_VSS",
"YES",
"REJ",
"XDO",
"DMZ",
"AND",
"NAR",
"CCL",
"FCT",
]
)
>>> grammar.try_tokens
`['AND',
'DMZ',
'FCT',
'NAR',
'NOT',
'PCE',
'PRP',
'QRY',
'REJ',
'XDO',
'YES',
'ALY',
'VSS']`
These two tokens are added unnecessarily.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.