Package: amr-logic-converter
AMR Logic ConverterConvert Abstract Meaning Representation (AMR) to first-order logic statements.This library is based on the ideas in the paper"Expressive Power of Abstract Meaning Representations", J. Bos, Computational Linguistics 42(3), 2016. Thank you to@jobosfor the paper!Installationpip install amr-logic-converterUsageThis library parses an AMR tree into first-order logic statements. An example of this is shown below:fromamr_logic_converterimportAmrLogicConverterconverter=AmrLogicConverter()AMR="""(x / boy:ARG0-of (e / giggle-01:polarity -))"""logic=converter.convert(AMR)print(logic)# boy(x) ^ ¬(:ARG0(e, x) ^ giggle-01(e))Programmatic logic manipulationThe output from theconvertmethod can be displayed as a string, but it can also be manipulated in Python. For instance, in the example above, we could also write:converter=AmrLogicConverter()AMR="""(x / boy:ARG0-of (e / giggle-01:polarity -))"""expr=converter.convert(AMR)type(expr)# <class 'amr_logic_converter.types.And'>expr.args[0]# Atom(predicate=Predicate(symbol='boy', alignment=None), terms=(Constant(value='x', type='instance', alignment=None),))Working with alignment markersThis library will parse alignment markers from AMR using thepenman library, and will includeAlignmentobjects from penman inPredicateandConstobjects when available. For example, we can access alignment markers like below:converter=AmrLogicConverter()AMR="""(x / boy~1:ARG0-of (e / giggle-01~3:polarity -))"""expr=converter.convert(AMR)expr.args[0].alignment# Alignment((1,))expr.args[1].body.args[1].alignment# Alignment((3,))Existentially Quantifying all InstancesIn"Expressive Power of Abstract Meaning Representations", all instances are wrapped by an existence quantifier. By defaultAmrLogicConverterdoes not include these as it's likely not useful, but if you'd like to include them as in the paper you can pass the optionexistentially_quantify_instances=Truewhen constructing theAmrLogicConverteras below:converter=AmrLogicConverter(existentially_quantify_instances=True)AMR="""(x / boy:ARG0-of (e / giggle-01:polarity -))"""logic=converter.convert(AMR)print(logic)# ∃X(boy(X) ^ ¬∃E(:ARG0(E, X) ^ giggle-01(E)))Coreference HoistingWhen an instance is coreferenced in multiple places in the AMR, it's necessary to hoisting the existential quantification of that variable high enough that it can still wrap all instances of that variable. By default, the existential quantifier will be hoisted to the level of the lowest common ancestor of all nodes in the AMR tree where an instance is coreferenced. However, in"Expressive Power of Abstract Meaning Representations", these coreferences are instead hoisted to the maximal possible scope, wrapping the entire formula. If you want this behavior, you can specify the optionmaximally_hoist_coreferences=Truewhen creating theAmrLogicConverterinstance. This is illustrated below:AMR="""(b / bad-07:polarity -:ARG1 (e / dry-01:ARG0 (x / person:named "Mr Krupp"):ARG1 x))"""# default behavior, hoist only to the lowest common ancestorconverter=AmrLogicConverter(existentially_quantify_instances=True,)logic=converter.convert(AMR)print(logic)# ¬∃B(bad-07(B) ∧ ∃E(∃X(:ARG1(B, E) ∧ person(X) ∧ :named(X, "Mr Krupp") ∧ dry-01(E) ∧ :ARG0(E, X) ∧ :ARG1(E, X))))# maximally hoist coferencesconverter=AmrLogicConverter(existentially_quantify_instances=True,maximally_hoist_coreferences=True,)logic=converter.convert(AMR)print(logic)# ∃X(¬∃B(bad-07(B) ∧ ∃E(:ARG1(B, E) ∧ dry-01(E) ∧ :ARG0(E, X) ∧ :ARG1(E, X))) ∧ person(X) ∧ :named(X, "Mr Krupp"))Using Variables for InstancesIf you want to use variables for each AMR instance instead of constants, you can pass the optionuse_variables_for_instances=Truewhen creating the AmrLogicConverter instance. Whenexistentially_quantify_instancesis set, variable will always be used for instances regardless of this setting.Misc OptionsBy default variables names are capitalized, but you can change this by settingcapitalize_variables=False.By default, relations like:ARG0-of(X, Y)have their arguments flipped in logic and turned into:ARG0(Y, X). If you don't want this normalization to occur, you can disable this by settinginvert_relations=False.ContributingContributions are welcome! Please leave an issue in the Github repo if you find any bugs, and open a pull request with and fixes or improvements that you'd like to contribute. Ideally please include new test cases to verify any changes or bugfixes if appropriate.This project usespoetryfor dependency management and packaging,blackfor code formatting,flake8for linting, andmypyfor type checking.LicenseThis project is licenced under a MIT license.