<commit_before>;
; chat-utils.scm
;
; Chatbot dialog utils.
; These include performing R2L processing and question-answering.
;
; Copyright (c) 2009 <NAME> <<EMAIL>>
; Copyright (c) 2015 OpenCog Foundation
;

(use-modules (ice-9 threads)  ; needed for par-map
             (srfi srfi-1)
             (opencog)
             (opencog atom-types)
             (opencog rule-engine)
             (opencog nlp)
             (opencog nlp fuzzy)
             (opencog nlp microplanning)
             (opencog nlp relex2logic))

; -----------------------------------------------------------------------
(define (r2l-parse sent)
"
  r2l-parse SENT -- perform relex2logic processing on sentence SENT.

  Runs the rules found in R2L-en-RuleBase over the RelEx output
  creating the logical representation of sentence in the atomspace.
  Returns a list containing SetLinks that are the r2l-interpretations
  for individual parses.

  This can't handle  mutliple thread execution (Why???). Thus, mapping
  this function over a list of sentences, even though possible, is not
  advised.

  SENT must be a SentenceNode.
"
    (define (cog-delete-parent a-link)
        ; Many rules return a ListLink of results that they
        ; generated. Some rules return singletons. And the
        ; Forward Chainer uses a SetLink to wrap all these
        ; results. So if A-LINK is a SetLink or a ListLink,
        ; then delete it and return a list of its contents,
        ; else return a list holding A-LINK.
        ;
        ; XXX maybe this should be part of the ure module??
        (if (or (equal? 'ListLink (cog-type a-link))
                (equal? 'SetLink (cog-type a-link)))
            (let ((returned-list (cog-outgoing-set a-link)))
                    (cog-delete a-link)
                    returned-list)
            (list a-link))
    )

    (define (run-fc parse-node interp-link)
        ; This runs all the rules of R2L-en-RuleBase over relex parse
        ; outputs, and returns a cleaned and de-duplicated list. The
        ; relex outputs associated with 'parse-node' make the focus-set.
        ; This is done so that, IF there are multiple parses, then
        ; each is handled independently by passing it seperately, as
        ; each is likely to exist in a seperate semantic-universe.
        (define focus-set
            (SetLink (parse-get-relex-outputs parse-node) interp-link))
        (define outputs
            (cog-delete-parent (cog-fc (SetLink) r2l-rules focus-set)))

        (append-map cog-delete-parent outputs)
    )

    (define (interpret parse-node)
        ; FIXME: Presently only a single interpretation is created for
        ; each parse. Multiple interpreation should be handled, when
        ; word-sense-disambiguation, anaphora-resolution and other
        ; post-processing are added to the pipeline.
        (let* ((interp-name (string-append(cog-name parse-node) "_interpretation_$X"))
               (interp-node (InterpretationNode interp-name))
               ; Associate the interpretation with a parse, as there
               ; could be multiplie interpretations for the same parse.
               (interp-link (InterpretationLink interp-node parse-node))
               (pre-result
                   (remove
                       (lambda (a) (equal? (cog-type a) 'ReferenceLink))
                       (delete-duplicates (run-fc parse-node interp-link))))
               (result (SetLink pre-result)))

            ; Construct a ReferenceLink to the output
            (ReferenceLink interp-node result)

            ; Time stamp the parse
            (AtTimeLink
                ; FIXME: maybe opencog's internal time octime should
                ; be used. Will do for now, assuming a single instance<commit_msg>To play safe<commit_after>;
; chat-utils.scm
;
; Chatbot dialog utils.
; These include performing R2L processing and question-answering.
;
; Copyright (c) 2009 <NAME> <<EMAIL>>
; Copyright (c) 2015 OpenCog Foundation
;

(use-modules (ice-9 threads)  ; needed for par-map
             (srfi srfi-1)
             (opencog)
             (opencog atom-types)
             (opencog rule-engine)
             (opencog nlp)
             (opencog nlp fuzzy)
             (opencog nlp microplanning)
             (opencog nlp relex2logic))

; -----------------------------------------------------------------------
(define (r2l-parse sent)
"
  r2l-parse SENT -- perform relex2logic processing on sentence SENT.

  Runs the rules found in R2L-en-RuleBase over the RelEx output
  creating the logical representation of sentence in the atomspace.
  Returns a list containing SetLinks that are the r2l-interpretations
  for individual parses.

  This can't handle  mutliple thread execution (Why???). Thus, mapping
  this function over a list of sentences, even though possible, is not
  advised.

  SENT must be a SentenceNode.
"
    (define (cog-delete-parent a-link is-from-fc)
        ; Many rules return a ListLink of results that they
        ; generated. Some rules return singletons. And the
        ; Forward Chainer uses a SetLink to wrap all these
        ; results. So if A-LINK is a SetLink or a ListLink,
        ; then delete it and return a list of its contents,
        ; else return a list holding A-LINK.
        ;
        ; XXX maybe this should be part of the ure module??
        (if (or (equal? 'ListLink (cog-type a-link)) is-from-fc)
            (let ((returned-list (cog-outgoing-set a-link)))
                    (cog-delete a-link)
                    returned-list)
            (list a-link))
    )

    (define (run-fc parse-node interp-link)
        ; This runs all the rules of R2L-en-RuleBase over relex parse
        ; outputs, and returns a cleaned and de-duplicated list. The
        ; relex outputs associated with 'parse-node' make the focus-set.
        ; This is done so that, IF there are multiple parses, then
        ; each is handled independently by passing it seperately, as
        ; each is likely to exist in a seperate semantic-universe.
        (define focus-set
            (SetLink (parse-get-relex-outputs parse-node) interp-link))
        (define outputs
            (cog-delete-parent (cog-fc (SetLink) r2l-rules focus-set) #t))

        (append-map (lambda (o) (cog-delete-parent o #f)) outputs)
    )

    (define (interpret parse-node)
        ; FIXME: Presently only a single interpretation is created for
        ; each parse. Multiple interpreation should be handled, when
        ; word-sense-disambiguation, anaphora-resolution and other
        ; post-processing are added to the pipeline.
        (let* ((interp-name (string-append(cog-name parse-node) "_interpretation_$X"))
               (interp-node (InterpretationNode interp-name))
               ; Associate the interpretation with a parse, as there
               ; could be multiplie interpretations for the same parse.
               (interp-link (InterpretationLink interp-node parse-node))
               (pre-result
                   (remove
                       (lambda (a) (equal? (cog-type a) 'ReferenceLink))
                       (delete-duplicates (run-fc parse-node interp-link))))
               (result (SetLink pre-result)))

            ; Construct a ReferenceLink to the output
            (ReferenceLink interp-node result)

            ; Time stamp the parse
            (AtTimeLink
                ; FIXME: maybe opencog's internal time octime should
                ; be used. Will do for now, assuming a single instance
{'fraction_non_alphanumeric': 0.09840425531914894, 'fraction_numerical': 0.0050531914893617025, 'mean_word_length': 1.989268680445151, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4872615', 'n_tokens_mistral': 2117, 'n_tokens_neox': 2035, 'n_words': 760}