Commit 3f142d6f authored by remivantrijp's avatar remivantrijp
Browse files

Improving the hybrid de-render for English.

parent 58048cec
......@@ -47,18 +47,10 @@
:serial t
:components ((:file "categories")
(:file "pos-tags")
(:file "clear-dependency-specs"))))))
;(:file "represent-structures"))))))
(:file "clear-dependency-specs")
(:file "represent-structures")
(:file "de-render")))))
(:file "examples"))
:description "Multilingual library for combining symbolic FCG-grammars with NLP tools. Currently, this is achieved by translating
output from the NLP-tools into transient structures, onto which FCG grammars can operate. In other words, this is
useful for integrating FCG as a step in an NLP-pipeline.")
;;; ;; Some examples of de-render methods using preprocessing tools with preprocessing:
;;; (:file "examples")
;;; (:module "english-hybrids"
;;; :serial t
;;; :components ((:file "categories")
;;; (:file "translate-dependency-tree")
;;; (:file "render")
;;; (:file "de-render"))))
\ No newline at end of file
......@@ -213,117 +213,4 @@
(defun object-predicate-p (label &optional (dependency-specs *english-dependency-specs*))
"Is the dependency relation an object predicate?"
(dependency-spec-member 'object-predicate (get-dependency-spec label dependency-specs)))
;;;;; ------------------------------------------------------------------------------------------
;;;;; Helper functions for data structures.
;;;;; ------------------------------------------------------------------------------------------
(defmethod retrieve-category-from-conversion-table ((category-name t)
(conversion-table clear-dependency))
(second (assoc category-name (clear-dependency-specs conversion-table)
:test #'string=)))
(defun lex-class-p (dependency-spec)
(eql 'lexical (second dependency-spec)))
(defun dependency-spec-category (dependency-spec)
(fourth dependency-spec))
(defun english-retrieve-category (word-spec)
(or (assoc (word-dependency-spec-syn-role word-spec) *functions-that-are-categories* :test #'string=)
(assoc (word-dependency-spec-pos-tag word-spec) *spacy-pos-tag-conversion-table* :test #'string=)))
(defun find-dependency-spec (dependency-tag)
"Get the information associated with a dependency-tag."
(assoc dependency-tag (clear-dependency-specs *dependency-specs*) :test #'string=))
(defun explain-dependency-tag (tag)
(nth 4 (find-dependency-spec tag)))
;; (explain-dependency-tag "oprd")
;;;;; ------------------------------------------------------------------------------------------
;;;;; Knowledge about the Translation.
;;;;; ------------------------------------------------------------------------------------------
(defun subject-p (tag)
(member 'subject (find-dependency-spec tag)))
;; (subject-p "nsubj")
;; (subject-p "dobj")
(defun passive-subject-p (tag)
(member tag '("nsubjpass" "csubjpass") :test #'string=))
(defun object-p (tag)
(member 'object (find-dependency-spec tag)))
;; (object-p "dobj")
;; (object-p "nsubj")
(defun indirect-object-p (tag)
(member 'indirect-object (find-dependency-spec tag)))
;; (indirect-object-p "dative")
(defun dative-p (tag)
(indirect-object-p tag))
;; (indirect-object-p "dative")
(defun core-function-p (tag)
(or (subject-p tag)
(object-p tag)
(dative-p tag)))
(defun clausal-dependent-p (tag &optional pos-tag)
(or (member 'clausal (find-dependency-spec tag))
;; In some cases, we might have a clausal complement.
;; We check whether the head is verbal.
(and pos-tag
(member 'it-depends (find-dependency-spec tag))
(string= "V" (subseq pos-tag 0 1)))))
;; (clausal-dependent-p "csubj")
(defun functional-dependent-p (tag)
(member 'functional (find-dependency-spec tag)))
;; (functional-dependent-p "nsubj")
;; (functional-dependent-p "det")
(defun verbal-root-p (root)
(string= "V" (subseq (word-dependency-spec-pos-tag root) 0 1)))
(defun verb-p (word-spec)
(let ((pos-tag (word-dependency-spec-pos-tag word-spec)))
(or (string= "V" (subseq pos-tag 0 1))
(string= "MD" pos-tag)))) ;; For modal auxiliaries.
(defun adjective-p (word-spec)
(member (word-dependency-spec-pos-tag word-spec)
'("JJ" "JJR" "JJS") :test #'string=))
(defun by-phrase-p (word-spec)
(string= "agent" (word-dependency-spec-syn-role word-spec)))
(defun PrepNP-p (word-spec)
(string= "prep" (word-dependency-spec-syn-role word-spec)))
(defun auxiliary-p (word-spec)
(member (word-dependency-spec-syn-role word-spec)
'("aux" "auxpass") :test #'string=))
(defun negation-p (word-spec)
(string= "neg" (word-dependency-spec-syn-role word-spec)))
(defun dependency-root-p (word-spec)
(string= "ROOT" (word-dependency-spec-syn-role word-spec)))
(defun adverbial-modifier-p (function-or-word-spec)
(string= "advmod" (if (eql (type-of function-or-word-spec) 'word-dependency-spec)
(word-dependency-spec-syn-role word-spec)
function-or-word-spec)))
(defun particle-p (word-spec)
(string= "prt" (word-dependency-spec-syn-role word-spec)))
(defun genitive-p (word-spec)
(string= "case" (word-dependency-spec-syn-role word-spec)))
(defun possessor-p (word-spec)
(string= "poss" (word-dependency-spec-syn-role word-spec)))
\ No newline at end of file
(dependency-spec-member 'object-predicate (get-dependency-spec label dependency-specs)))
\ No newline at end of file
;; Copyright 2019-present
;; Sony Computer Science Laboratories Paris
;; Remi van Trijp (http://www.remivantrijp.eu)
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;; http://www.apache.org/licenses/LICENSE-2.0
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;;=========================================================================
(in-package :fcg)
(defmethod de-render ((utterance string) (mode (eql :english-hybrid))
&key (key :english) cxn-inventory (model "en") &allow-other-keys)
(declare (ignorable mode cxn-inventory))
; Step 1: Get the dependency and constituent analysis:
(multiple-value-bind (dependency-tree constituent-tree)
(get-english-sentence-analysis utterance)
(let* (; Step 2: Use the dependency tree for segmenting the utterance into a list of strings:
(utterance-as-list (nlp-tools::dp-build-utterance-as-list-from-dependency-tree dependency-tree))
;; Step 3: Use the list of strings for building a basic transient structure:
(basic-transient-structure (de-render utterance-as-list :de-render-with-scope
:cxn-inventory cxn-inventory)))
;; Step 4: Expand the transient structure with information from the dependency tree:
(setf basic-transient-structure
(represent-functional-structure dependency-tree basic-transient-structure key *english-dependency-specs*))
;; Step 5: Expand the transient structure with information from the constituent tree:
(setf basic-transient-structure
(represent-constituent-structure constituent-tree basic-transient-structure key cxn-inventory))
basic-transient-structure)))
......@@ -92,7 +92,7 @@
(defmethod represent-constituent-structure ((constituent-tree list)
(transient-structure coupled-feature-structure)
(key (eql :english-hybrids))
(key (eql :english))
(cxn-inventory t)
&optional (language t))
"Represent constituent structure using BeNePar, assuming already a dependency structure."
......@@ -129,11 +129,9 @@
(first constituent)))))
(setf queue (append new-nodes-to-queue queue))
(push `(,unit-name
,@(find-all-features-for-category (fetch-syntactic-category category) *english-fcg-categories*
,@(find-all-features-for-fcg-category (fetch-syntactic-category category) *english-fcg-categories*
:features-so-far `(,@(if parent `((parent ,parent)))
(constituents ,(mapcar #'second new-nodes-to-queue))
(node-accessor
,(format nil "~a-~a" category (length new-nodes-to-queue))))))
(constituents ,(mapcar #'second new-nodes-to-queue)))))
units)))
;; Now we reiterate
(go start))
......@@ -162,87 +160,4 @@
(let ((new-root (calculate-boundaries-and-form-constraints transient-structure nil cxn-inventory)))
(setf (left-pole-structure transient-structure)
(cons new-root units))
transient-structure))))
;; (de-render "Luc Steels was the first director of Sony CSL Paris." :beng-spacy-benepar)
;; (comprehend "if the can get sufficient funding")
;; (dev-tools:dev-construction-tutor)
(defmethod de-render ((utterance string) (mode (eql :english-hybrid))
&key (key :english) cxn-inventory (model "en") &allow-other-keys)
(declare (ignorable mode cxn-inventory))
(let* (; Step 1: Get the dependency tree:
(dependency-tree (nlp-tools:get-penelope-dependency-analysis utterance :model model))
; Step 2: Use the dependency tree for segmenting the utterance into a list of strings:
(utterance-as-list (nlp-tools::dp-build-utterance-as-list-from-dependency-tree dependency-tree))
;; Step 3: Use the list of strings for building a basic transient structure:
(basic-transient-structure (de-render utterance-as-list :de-render-with-scope
:cxn-inventory cxn-inventory)))
;; Step 4: Expand the transient structure with information from the dependency tree:
(represent-functional-structure dependency-tree basic-transient-structure key *english-dependency-specs*)))
;; (de-render "the thief was caught by the police" :english-hybrid)
;;; (structure-to-append (loop for word-spec in word-specs
;;; for dependent-word-specs =
;;; (loop for other-word-spec in word-specs
;;; when (and (not (equal word-spec other-word-spec))
;;; (= (word-dependency-spec-head-id other-word-spec)
;;; (word-dependency-spec-node-id word-spec)))
;;; collect other-word-spec)
;;; for dependents = (mapcar #'word-dependency-spec-unit-name dependent-word-specs)
;;; for functional-structure =
;;; (loop for other-word-spec in dependent-word-specs
;;; for function = (word-dependency-spec-syn-role
;;; other-word-spec)
;;; collect (cond
;;; ((subject-p function)
;;; `(subject
;;; ,(word-dependency-spec-unit-name
;;; other-word-spec)))
;;; ((object-p function)
;;; `(object ,(word-dependency-spec-unit-name
;;; other-word-spec)))
;;; ((indirect-object-p function)
;;; `(indirect-object
;;; ,(word-dependency-spec-unit-name
;;; other-word-spec)))
;;; ((adverbial-modifier-p function)
;;; `(adv-modifier
;;; ,(word-dependency-spec-unit-name
;;; other-word-spec)))
;;; (t
;;; nil)))
;;; collect
;;; (make-unit :name (word-dependency-spec-unit-name word-spec)
;;; :features
;;; (find-all-features-for-category
;;; (english-retrieve-category word-spec)
;;; *english-grammar-categories*
;;; :features-so-far `((dependents ,dependents)
;;; (pos ,(word-dependency-spec-pos-tag word-spec))
;;; ,@(if functional-structure
;;; `((functional-structure ,functional-structure)
;;; ,@(dolist (other-spec word-specs)
;;; (cond ((passive-subject-p
;;; (word-dependency-spec-syn-role
;;; other-spec))
;;; (return `((voice passive))))
;;; ((subject-p
;;; (word-dependency-spec-syn-role
;;; other-spec))
;;; (return `((voice active))))
;;; (t
;;; nil)))))))))))
;;; (setf (left-pole-structure transient-structure)
;;; (append (left-pole-structure transient-structure) structure-to-append))
;;; transient-structure))
transient-structure))))
\ No newline at end of file
......@@ -89,24 +89,4 @@
(setf (left-pole-structure transient-structure)
(append (left-pole-structure transient-structure) new-units))
(set-data transient-structure :dependency-tree dependency-tree)
transient-structure))
;; 2- Dependency conversion tables.
;; ------------------------------------------------------------------------------------------------
(export '(fcg-get-dependency-conversion-table fcg-set-dependency-conversion-table))
(defgeneric retrieve-category-from-conversion-table (category-name conversion-table))
(defmethod retrieve-category-from-conversion-table ((category-name t)
(conversion-table list))
(second (assoc category-name conversion-table)
:test #'equal))
(defun fcg-get-dependency-conversion-table (&optional cxn-inventory)
(or (when cxn-inventory (get-configuration cxn-inventory :dependency-conversion-table))
t)) ;; At least always return T.
(defun fcg-set-dependency-conversion-table (cxn-inventory data)
(set-configuration cxn-inventory :dependency-conversion-table data))
transient-structure))
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment