mscarey / authorityspoke Goto Github PK
View Code? Open in Web Editor NEWReading legal authority for the last time
Home Page: https://authorityspoke.readthedocs.io
License: Other
Reading legal authority for the last time
Home Page: https://authorityspoke.readthedocs.io
License: Other
Factor subclass instances need to be created with a call to e.g. Fact(), not Fact.new(), regardless of the inconvenience of post_init for frozen classes. Unless it irrevocably breaks hash.
It's not clear how to represent this in authorityspoke:
“Federal constitutional standards generally govern our review of claims that evidence is inadmissible because it was obtained during an unlawful search.” (People v. Willis (2002) 28 Cal.4th 22, 29 [120 Cal.Rptr.2d 105, 46 P.3d 898]
what about mandatory/universal/valid tags?
Instead of having mentioned
be a list of Factor
s and factor_text_links
a dict with Factor
s as keys, mentioned
will be a dict with the values from factor_text_links
.
This means the TextQuoteSelector
s for each Factor
will probably be created in a function that decorates read_factor
(formerly Factor.from_dict
) rather than in the middle of read_holding
(formerly Holding.from_dict
).
A function to determine if a factor implies another (transitively) given a list of factors that imply one another or a function for determining which implication relations (represented by production rules?)
are binding from the point of view of a particular court.
An operator to reflect the idea that if you have all the inputs needed for two discrete Rules, you can get all the outputs for both Rules (but think about the effect of universal/mandatory, of course).
This will cause Entity objects potentially to be nested at various levels of a tree of Predicates, so they'll all need to be collected and ordered to test whether they match the entities from another Factor.
But ultimately it's possible to serialize the Entities into an unambiguous order, since any Factor can be turned into an English phrase with the words in a known order.
Maybe this will require moving entity_context attributes from Factor to Predicate?
Here's an example of a Fact object that can't be created yet.
Fact(It is relevant to
Fact(Defendant is guilty of theft)
that there is
Evidence(Cashier's statement that
Fact(Defendant took money from the register)
)
)
Try thinking about these references as shallow references, not deep copies.
By default, it seems overly picky to require the second Rule to have fewer Enactments for them to be added together, because it's reasonable to assume they're being added for use in a context where all the relevant Enactments can be available.
But maybe create a .add method that doesn't use the + operator, and allows a parameter for non-default behavior that would return None in this case.
If two Opinions posit Rules that aren't identical, you often need to know the broadest Rule that's supported by both Opinions (which means "implied by some Rule in each Opinion"?).
Similar to a set intersection in logic, the &
operator should answer this question for two Rules.
This would be a single object type that could both link a holding to Opinion text, and link a Rule to Enactment text. Look at web standards for annotation.
The concept of assigning a date to a pleading is too ambiguous, in some contexts, to model by simply linking a datetime as an attribute to the Pleading object.
For instance:
Mentioned = Dict[Union[Factor, Enactment], List[TextQuoteSelector]]]
And then the type annotation for that concept would be simplified to Mentioned
.
Similar problem exists with the concept of a context_register
in the factors module.
Some rules are found in Enactment text and don't need the support of an Opinion.
For instance, when Oracle v. Google (750 F.3d 1339) says this:
By statute, a work must be “original” to qualify for copyright protection. 17 U.S.C. § 102(a).
it's really only pointing out the statute text and not really positing its own rule. It would be better if that rule was linked directly to the statute text.
Maybe when a Factor pair with interchangeable context factors gets merged into a context_register, it needs to create new context_registers with the interchangeable factors swapped.
Make an understandable interface that doesn't require some of the parameters to come packed in a dict. Then change the names of this method and of Factor.from_dict to reflect the difference between this and the regular constructor method. Maybe Enactment.factory()?
If two different generic factors are in the same role in two different Rules being joined with the union operator, then the method should infer that the generic factor in that role in the incoming Rule can be replaced with the Factor in that role in the existing Rule.
Probably this will cause a lot of problems and it will be very hard to make the method do what users' common sense would lead them to expect.
It's not clear to me that there's an adequate test of Factor equality when the comparison methods are searching for pairs of interchangeable context Factors. In particular, is it possible for different generic Entity subclasses to be equal even when they're clearly inconsistent?
One place to put an equality check might be Factor.registers_for_interchangeable_context()
Currently the context_factors property is a tuple of Factors corresponding to the objects attributes for several classes like Evidence, but for Fact there's one attribute (not a property) called context_factors, which contains a sequence of factors. And for Procedure, the property context_factors is a tuple of tuples of Factors (the inner tuples correspond to the attributes input, output, and despite).
I need a generic way to specify a context_factors property, whether it has single Factors, tuples of Factors, or both. Then maybe I can consolidate the different methods for working with context_factors depending on what shape they're in.
I think these names are an artifact of a time when exposit
was a factory function.
Users need to be able to access all of the selected text for a Holding (including all of the Holding's Factors) for viewing. This function should still be abstracted from the specific output medium, whether that will be Jupyter Notebook or Flask
Overloading __eq__
has been fun. It may be time for the fun to stop.
some_rule + some_factor
would currently throw an error.
Maybe instead it should return a new version of the Rule with the Factor added to the Rule's inputs. Similarly some_rule + some_enactment
could add to the enactments attribute.
currently there's Procedure.new_context() and the entire concept of a Holding object.
Probably I need to stick with Procedure.new_context(). The Holding object at first glance seems to link all Holdings with the same meaning to the same ProceduralRule object, but realistically, there's no way to prevent multiple ProceduralRule objects with the same meaning from being created, so the Holdings class just adds a confusing abstraction that doesn't solve the deduping problem or any other problem.
Designating an object to be a member of an Entity subclass such as Association, rather than just an Entity, seems to be equivalent to creating a Fact that "X was an association", so there will still be a way to accomplish the same thing if the feature is removed.
But if it stays in, I don't know how to represent the concept that Rule A applies to Association X notwithstanding the fact that Rule A was about a regular Entity rather than an Association.
In the Introduction notebook, I wasn't able to do this:
nosferatu_rule = lotus_majority.holdings[0].new_context(
{Association('Borland International'): Human('F.W. Murnau'),
Entity('the Lotus menu command hierarchy'): Entity("Dracula")}
)
assert nosferatu_rule.means(lotus_majority.holdings[0])
And I can't think of any reasonably easy way to do it.
I want to let Factor.means
, .implies
, and .contradicts
return a Factor that uses the context_factors from other to show how self
means, implies, or contradicts other
. This would be a parameter to each method that causes them to return Union[Factor, None]
instead of the usual bool
.
A drawback to this plan is that it could be confusing that one returns None
for "no match" and the other returns False
.
The trier parameter could label a Fact as having been found by a judge, jury, magistrate, or arbitrator.
The identity of a particular judge, magistrate, or arbitrator probably shouldn't be linked to a Fact through the trier parameter though. Unless it was linked with generic context.
The rule_valid and decided attributes of Rule aren't very helpful when adding Rules together. Maybe it's time for a separate class called a Holding that represents the relationship between an Opinion and a Rule. The Holding class could have the rule_valid
and decided
attributes as well as the text selector showing which part of the Opinion text is the basis for the Holding.
Right now pairs of Factors that grammatically correspond to each other are stored as key-value pairs. But this broke when a factor needed to refer to two other factors, because a Fact with a quantity comparison implied two other Facts. It seems like for the bug to arise, the implying fact ended up as a key once and a value once. Not sure how that happened with a some-to-some comparison, but it would definitely happen with all-to-all, because that requires self's factors to imply other's sometimes, and sometimes vice versa.
Maybe every implication relationship needs a key-value entry (with a list of multiple values allowed), but equality entries need to be entered in reverse as well.
Or maybe the dict should be for generic context factors only, and comparison of non-generic factors should happen elsewhere. Limiting dict entries to just generic Factors broke test_implication_complex(), but maybe that's a glitch I can get around.
with tests
It might be better if passages of text used for Predicates were sequences of spaCy tokens rather than regular Python strings.
SpaCy's entity extraction feature could be used to find likely candidates to create AuthoritySpoke Entity objects.
And it could be used for passages in Enactments as well.
This could be three issues, not very fleshed out.
It's not that helpful to teach users how to use a JSON input format that's still in flux. It's more impactful to show how to load holdings from existing JSON files and automate analysis tasks on them. Creating JSON input is a more advanced function beyond the introductory tutorial.
Currently it passes to implies(other.evolve(absent=True)), which then passes back to contradicts_if_present.
Instead of requiring a procedure parameter, optionally let users specify outputs
, inputs
, despite
, and use those to build a Procedure object behind the scenes.
Otherwise Procedure objects will need to be built inside the Rule constructor, which makes it look even more complex and intimidating.
Similarly it could become possible to skip constructing a Predicate when making a Fact.
This could involve consolidating the regular constructors with the from_dict constructors and the JSON input format. See #22.
Currently it compares all of self
's factors to other
's, and then compares other
's to self
. Most aspects of this calculation are repeated between the two steps.
Currently the value for the list of text selectors is set for each Factor/Enactment key as [] when the key is added. Could have used this:
mentioned = defaultdict(list)
If the outputs of Rule A can function as the inputs of Rule B, the addition operator creates a new Rule with the inputs of Rule A and the outputs of (both A and B?) (but only if one of the Rules is an ALL Rule?).
Should there also be a union operator so that the union of Rules C and D would have all the inputs as well as all the outputs of both C and D (which would probably also require ALL)?
These operators could then be used to check whether Rules contradict each other in the context of background knowledge. See issue #2.
The new line breaks and all-caps labels look good in the str() methods, but they're not okay when the text of a context factor is being inserted in a Predicate.
Maybe I can get rid of the caps and colons, and just delete the whitespace to make the strings fit in the Predicates again. Or maybe I should resurrect the string methods I just deleted, but use them only for insertion in a Predicate.
Here's an example from Cardenas.holdings[1]:
the Fact that
> the Exhibit in the FORM of testimony
> STATED BY <parole officer>
> ASSERTING:
> the Fact that the <defendant> was addicted to heroin
was relevant to show <defendant> had a motive to commit an attempted robbery
The Exhibit object is in the middle of the Fact, bringing along its own line breaks and indentation
Instead, Enactment could just have its uri/path to the Code and the description of its text in Enactment.selector.
That way, a larger unhashable Code object wouldn't have to be an attribute of a smaller hashable Enactment object.
The requirements for two Rules to be joined using Rule.__or__
are probably equivalent to the test in Factor.consistent_with
. They can probably be rewritten so that one reuses the other's code.
The .from_dict methods are part of the process of creating authorityspoke objects from JSON, so they should be in the io
folder or somewhere else outside the core modules. Also Enactment.__post_init__
.
use attrs library to create/evolve frozen dataclasses
If the same generic factor is inserted twice as a key in a ContextRegister, it's going to be overwritten and cause errors.
It's awkward to divide the JSON input format into "mentioned_factors" and "holdings". I could avoid this by declaring new Entities within the Fact objects where they appear.
I could also allow Entities to be declared just by putting brackets around their text, but that wouldn't work in cases where the Entity needs to be identified as concrete, so "mentioned" elements within a Factor need to be still allowed.
It should be allowed to declare Entities in any Factor, regardless of the order they come in (and they should be recognized in earlier Factors).
This method seems to duplicate a calculation that should be handled by the Analogy class.
This JSON should create a valid Fact (where "Lotus 1-2-3" is a reference to an Entity):
{
"type": "fact",
"content": "the precise formulation of Lotus 1-2-3's code was not necessary for Lotus 1-2-3 to work"
}
It's not convenient to write a list of necessary inputs for an output, like an elements test.
For instance, this holding would be broken down into three Rules:
"To establish copyright infringement, a plaintiff must prove (1) ownership of a valid copyright, and (2) copying of constituent elements of the work that are original." (49 F.3d 807)
That's not concise.
This same problem exists in holdings_brad.json.
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.