추상 위키백과/위키함수용 템플릿 언어/스크리분토 기반 구현

이것은 추상 위키백과 프로젝트에서 사용할 NLG 템플릿 언어를 만들기 위한 제안을 기반으로 하는 Scribunto 기반 NLG 시스템의 개요 문서 페이지입니다. Scribunto 기반 시스템에는 두 가지 목표가 있습니다. 첫째, 위키함수 자체에서 유사한 시스템의 향후 구현을 알릴 수 있는 프로토타입 구현으로 작동하고, 둘째, Scribunto 환경 내에서 위키데이터 어휘집을 기반으로 하는 독립형 NLG 시스템으로 작동합니다.

시스템 데모

이 페이지는 두 부분으로 구성됩니다:

  1. 코드 흐름에 대한 설명;
  2. 특정 언어에 대한 새로운 추상 콘텐츠 또는 렌더러를 작성하려는 기여자를 위한 지침입니다.

코드 흐름: Q-id에서 언어화된 콘텐츠로

시스템에서 사용되는 다양한 모듈에는 자체 설명서 페이지가 있습니다. 이 섹션의 목표는 구성 요소가 함께 작동하는 방법에 대한 개요를 제공하는 것입니다.

프로그램의 흐름은 추상 위키백과에 대해 제안된 NLG 아키텍처를 밀접하게 따릅니다.

 

Q-id에서 템플릿으로

내용 언어화의 진입점은 (프레임 객체에서) Q-id와 (선택 사항) 실현 언어 코드를 취하는 content 함수입니다(언어 코드를 지정하지 않으면 해당 사용자의 위키 기본 언어가 대신 사용됨).

콘텐츠 검색

content 함수는 먼저 생성자 모듈을 사용하여 주어진 Q-id에 대한 추상 콘텐츠(즉, 인스턴스화된 생성자)를 검색합니다. 이 콘텐츠는 다음 두 가지 유형 중 하나일 수 있습니다:

  • 추상 콘텐츠 모듈에 저장된 지정된 Q-id에 대해 수동으로 선별된 추상 콘텐츠입니다.
  • Q-id가 참조하는 위키데이터 항목의 위키데이터 속성을 기반으로 동적으로 생성된 추상 콘텐츠(생성자 모듈의 코드에 의해).

이 두 가지 콘텐츠 검색 모드는 모델 문서 업데이트에서 논의되었습니다.

검색된 콘텐츠는 생성된 문서의 개요와 일치해야 하는 인스턴스화된 생성자 목록의 형식을 취합니다.

템플릿 선택

콘텐츠 목록인 각 생성자에 대해 적절한 템플릿을 선택하고 구현해야 합니다. content 함수 내에서 {root:main} 형식의 "래퍼 템플릿"을 실현하는 동시에 템플릿 실현 함수에 main이라는 단일 템플릿 인수를 전달하는 동안 콘텐츠 함수 내에서 콘텐츠가 구성자 자체입니다. 템플릿 실현 로직(아래에 자세히 설명됨)은 이를 main 인수의 "보간"(즉, 언어화)을 요청하는 단일 슬롯이 있는 템플릿으로 해석합니다. 생성자인 인수를 보간하려면 적절한 템플릿을 가져와야 하므로 생성자별 템플릿(지정된 실현 언어용)으로 래퍼 템플릿을 확장하는 것과 같습니다.

템플릿 구현

템플릿 실현의 주요 흐름은 realizeTemplate 함수 내에서 수행됩니다. 이 함수는 render 함수(여기에 설명되어 있음)을 사용하여 위키 페이지에서 직접 호출할 수도 있습니다. 이는 디버깅 목적이나 임시 템플릿을 구현해야 하는 경우에 유용합니다.

템플릿 실현은 템플릿 언어에 대해 지정된 일반 실현 알고리즘을 밀접하게 따르는 여러 단계로 구성됩니다(해당 알고리즘의 해당 단계는 아래 괄호 안에 지정됨).

초기화

initialize 함수는 구현 파이프라인 전체에서 사용할 일부 전역 변수를 설정합니다. 이들은 다음과 같습니다:

  • language 변수는 실현 언어의 언어 코드를 보유합니다. 사용자가 제공하거나 프로젝트의 콘텐츠 언어로 설정됩니다.
  • functions 변수는 템플릿에서 접근할 수 있는 모든 함수에 대한 테이블입니다. 이는 언어별 구현을 가리키거나, 그렇지 않은 경우 언어에 구애받지 않는 구현을 가리킵니다.
  • relations 변수는 템플릿에서 접근할 수 있는 모든 관계 함수에 대한 테이블입니다. 이는 언어별 구현을 가리키거나, 그렇지 않은 경우 언어에 구애받지 않는 구현을 가리킵니다.
  • renderers 변수는 생성자의 언어별 렌더러에 대한 테이블입니다.
  • applyPhonotactics 변수는 음소 배열론 모듈의 언어별 구현을 가리킵니다.

위키함수에서 이러한 모든 요소(실현 언어 코드 제외)는 위키함수 함수로 전역적으로 접근할 수 있어야 합니다.

템플릿 구문 분석 및 평가(1단계 및 2단계)

evaluateTemplate 함수(TemplateEvaluator 모듈의 일부)는 위 순서도(템플릿 렌더러)에서 첫 번째 사각형 상자의 실행을 담당합니다. 그것의 출력은 뿌리가 있는 어휘소 목록입니다. 순서가 있는 요소 목록은 그 자체가 어휘소이거나 뿌리가 있는 어휘소 목록이며 이러한 요소 중 하나를 루트로 식별하는 추가 root 필드가 있습니다. 위 순서도에서 이 데이터 구조의 이름은 "표제어 트리"입니다. 사실상 이것은 모든 노드가 루트 노드의 자식인 얕은 트리입니다(그러나 이 트리는 동일한 루트를 공유한다는 점을 제외하면 템플릿의 종속 관계에 의해 지정된 것과 반드시 동일하지는 않습니다).

이 단계는 세 부분으로 구성됩니다:

  1. TemplateParser 모듈의 구문 분석 함수는 문자열로 제공된 템플릿을 두 개의 목록으로 변환하기 위해 호출됩니다. 해당 요소의 구조화된 목록 표현과 적용할 종속성 관계의 목록 표현입니다. 파서는 루트 요소 목록 표현에 저장될 루트 요소의 인덱스도 반환합니다. 정확한 반환 형식은 모듈 설명서를 참조하십시오.
  2. evaluateElements 함수는 요소 목록을 순회하고 모든 템플릿 요소를 어휘소 또는 루트 어휘소 목록 표현으로 평가합니다. 평가는 각 요소의 유형에 따라 수행됩니다:
    • 숫자(슬롯 내)는 TemplateText 함수를 사용하여 평가됩니다.
    • 숫자(슬롯 내)는 Cardinal 함수를 사용하여 평가됩니다.
    • 어휘소 식별자(슬롯 내), 일명 L-id는 Lexeme 함수를 사용하여 평가됩니다.
    • 항목 식별자(슬롯 내), 일명 Q-id는 Label 함수를 사용하여 평가됩니다.
    • 인수의 보간은 인수를 가져온 다음 위와 동일한 논리를 사용하여 평가함으로써(evaluateInterpolation 함수에서) 평가됩니다(예: 인수가 L-id인 경우 Lexeme 함수를 사용하여 평가됨). 다음과 같은 경우 특수 논리가 적용됩니다.
      • 인수가 하위 템플릿(즉, { }을 포함하는 문자열)으로 평가되는 경우 해당 하위 템플릿은 evaluateTemplate 함수를 사용하여 재귀적으로 평가됩니다(루팅된 어휘소 목록 반환).
      • 인수가 변형 템플릿 목록(템플릿 필드를 포함하는 테이블 목록)으로 평가되는 경우 사전 조건에 따라 하나의 적절한 템플릿이 선택되고(selectTemplate 함수에 의해) 평가됩니다.
      • 인수가 생성자(즉, _predicate 필드를 포함하는 테이블)로 평가되면 해당 템플릿이 적절한 언어별 렌더러 모듈에서 가져와서(주어진 전제 조건에 따라) 평가됩니다(이는 evaluateConstructor 함수에서 발생).
    • 함수는 주어진 인수로 해당 함수를 호출하여 평가됩니다(evaluateFunction 함수에서). 함수에 인수로 전달된 함수 및 보간은 재귀적으로 평가되지만(evaluateFunctionArgument에서) 다른 인수 유형이 추가 처리 없이 호출된 함수에 단순히 문자열 인수로 전달되는 것은 아닙니다.
  3. 템플릿에 지정된 관계가 적용됩니다(applyRelations에서). 기본적으로 관계 모듈(또는 언어별 구현)에 정의된 알려진 관계 함수에 해당하는 모든 관계가 관련 요소에 적용됩니다(또는 요소가 루팅된 어휘소 목록으로 평가된 경우 해당 루트). 이러한 관계 함수는 지정된 문법 함수에 따라 두 인수의 문법적 특징을 통합하여 전체 언어 구조에 따라 어휘 간의 문법적 특징을 효과적으로 전파하고 공유합니다.

형태 통제 제약 적용(3단계, 관대한 가지치기 사용)

마지막 단계의 출력은 어휘소 트리이며, 각 어휘소는 다른 어휘소에서 유래할 수 있는 일련의 문법적 특징과 연관됩니다. 이러한 기능은 이제 각 어휘소의 형식 목록을 정리하는 제약 조건으로 작용할 수 있으므로 제약 조건을 준수하는 형식만 유지됩니다. 이 단계에서 트리 구조는 더 이상 필요하지 않으므로 단순한 어휘 목록으로 병합됩니다.

어휘소 가지치기는 어휘소 모듈filterForms 메서드를 호출하여 applyConstraints 함수에서 발생합니다. 필터링 알고리즘은 다음과 같이 작동합니다:

  • 모든 형태의 어휘소를 반복합니다. 각 양식에 대해:
    • 어휘소와 관련된 문법 제약 조건을 반복합니다. 각 문법 제약 범주에 대해:
      • 양식에 동일한 범주의 기능이 있는 경우:
        • 양식의 기능을 제약조건의 기능과 통합할 수 없는 경우 양식을 폐기하고 다음 양식으로 이동합니다.

프로토타입 구현에서 모든 기능은 자체 또는 빈 기능으로만 통합할 수 있습니다. 본격적인 구현에서는 기능의 언어적 계층 구조가 바람직할 수 있으므로 기능을 하위 또는 상위 기능과 통합할 수 있습니다. 위의 알고리즘은 양식과 어휘소의 제약 조건 간에 공유되는 범주의 기능이 통합 가능(즉, 호환 가능)하도록 보장하여 제약 조건에서 언급되지 않은 양식의 추가 기능을 허용합니다. 더 엄격한 가지치기 알고리즘은 양식의 기능이 어휘소에 부과된 제약 조건의 하위 집합임을 보장할 수 있지만 각 양식의 기능(위키데이터에서 가져옴)을 완전히 제어할 수 없기 때문에 위의 알고리즘이 선호됩니다.

이 잘라내기 알고리즘은 단항 특성과 잘 작동하지 않습니다. 예를 들어 양식에 표시되거나 표시되지 않을 수 있지만 다른 기능에 반대하지 않는 기능입니다(예: 약어 영어 동사를 표시할 수 있는 축약 기능). 이러한 기능은 제약 조건에 표시되든 양식에 표시되든 이 가지치기 알고리즘의 영향을 받지 않습니다(알고리즘은 기능 부족이 모든 기능과 호환된다고 가정하기 때문에). 이러한 기능의 지원이 필요한 경우 이러한 기능이 제약 조건과 양식의 기능 모두에 존재하는지 여부를 확인하기 위해 추가 단계를 추가해야 합니다.

이상적으로 가지치기 알고리즘은 어휘소의 정확히 한 가지 형식을 유지해야 합니다. 실제로는 여러 형태가 지속될 수 있습니다. 이러한 경우 덜 표시된 양식을 일관되게 출력하기 위해 양식은 sortForms 함수의 표준 순서에 따라 정렬됩니다. 이 함수는 cannonical_order 테이블에 지정된 대로 범주 및 기능에 대한 사전식 순서에 따라 양식을 정렬합니다. 예를 들어, 구두 어휘소에 사람 특징이 지정되지 않은 경우 어휘소의 다양한 인칭 어조가 가지치기 프로세스를 유지하지만 정렬은 3인칭 형식이 먼저 표시되도록 합니다(어휘소의 원래 형태 중에 존재하는 경우).

이 단계의 출력은 어휘소 목록이며, 각 어휘소에는 어휘소에 부과된 문법적 제약과 호환되는 가지치기된 형식 목록이 있습니다. 파이프라인의 나머지 부분에서 추가 수정이 수행되지 않는 한 가지치기된 형식 목록의 첫 번째 형식이 NLG 텍스트 렌더링에 사용됩니다. (정리 프로세스에 존재하는 양식이 없으면 어휘소의 기본형이 폴백으로 사용됩니다.) 어휘소의 문자열 형식을 요청하면(내장 함수 tostring을 사용하여) 함수가 lexeme 모듈 내에서 재정의되었으므로 이 첫 번째 형식(또는 가능한 경우 보조정리)이 생성됩니다.

포노택틱 규칙 적용(4단계)

이 단계에서 언어별 음성 및 철자법 규칙을 적용해야 합니다. 일반적으로 형태는 인접한 형태(간격 및 빈 형태 무시)에 따라 포노택틱 변경을 겪을 수 있으므로 이 과정에는 형태의 선형 순회와 변경 대상의 적응이 필요합니다. 각 형식의 포노택틱 변형은 해당 형식의 기존 목록에 저장될 수 있으며, 이 경우 올바른 형식이 형식 목록의 첫 번째 위치로 승격되거나 목록의 기존 첫 번째 형식을 변경하는 특별한 규칙이 있을 수 있습니다(lexeme 모듈의 도우미 함수 replaceByForm 사용).

구체적으로 포노택틱스의 적용은 applyPhonotactics라는 함수로 이루어집니다. 이 함수는 (초기화 단계에서) Module:Sandbox/AbstractWikipedia/Phonotactics/xx 모듈에서 찾을 수 있는 언어별 구현에 연결되어 있습니다(여기서 xx는 언어 코드를 나타냄). 이러한 함수가 정의되어 있지 않으면 기본 no-op 함수가 적용됩니다.

예를 들어 영어 및 히브리어 구현을 볼 수 있습니다:

  • 영어 구현은 부정관사 "a"(표제어 및 품사로 식별됨)에 대한 어휘소를 스캔합니다. 이러한 어휘소가 발견되면 다음 어휘소(공백 및 빈 형식 무시)를 검사하고 모음으로 시작하는 경우 관사의 형식을 "an" 형식으로 대체합니다. 현재 구현에서는 형식이 모음으로 시작하는지 여부를 결정하는 데 간단한 정규식 목록이 사용됩니다. 이상적으로는 이 정보를 저장하고 각 어휘소에 대해 위키데이터에서 가져와야 합니다.
  • 히브리어 구현은 히브리어 프로클리틱스 이후에 발생하는 특정 철자법 및 음소 변경을 처리합니다. 어휘 목록을 스캔하고 보조 정리로 식별되는 proclitics이 발견되면 다음과 같은 어휘가 다음과 같은 방식으로 변경될 수 있습니다.
    • proclictics 다음 공백이 제거됩니다.
    • 정관사(품사로 식별됨)는 특정 proclictics 다음에 제거됩니다.
    • proclitic 뒤에 숫자로 표기된 숫자가 오는 경우 히브리어 철자법에 따라 하이픈이 추가됩니다.
    • Proclictic 뒤에 문자 Vav로 시작하는 단어가 있으면 해당 문자는 무성 텍스트의 히브리어 작성 규칙에 따라 두 배가 됩니다.

이 단계의 출력은 어휘소 목록이며, 여기서 각 어휘소는 첫 번째 형식으로 그에 부과된 형태통제 및 음성적 제약과 호환되는 형식을 가져야 합니다.

최종 텍스트 구성(5단계)

렌더링된 텍스트의 생성은constructText 함수에서 수행됩니다. 기본적으로 이 함수는 이전 단계에서 전달된 모든 어휘소의 문자열 표현을 연결합니다. 어휘소의 문자열 표현은 일반적으로 형식 목록의 첫 번째 형식이며 음성 및 형태 구문 제약 조건에 해당해야 합니다. 이 작업을 수행하는 동안 함수는 공백 및 구두점의 특수 렌더링도 처리하고 필요한 대문자를 적용합니다. 현재 이 효과를 위해 다음 규칙이 구현됩니다.

  • 연속 spacing 어휘소(예: 공백만 포함하는 어휘소)가 있으면 마지막 어휘만 유지됩니다. 이는 빈 문자열로 평가된 슬롯 주위에 발생할 수 있는 여러 연속 공백을 방지하기 위해 필요합니다.
  • 후행 문장 부호가 연속적으로 나타나면(trailing_punctuation 테이블에 정의된 대로) 우선 순위가 가장 높은 문장 부호만 유지됩니다(예: 점이 쉼표를 억제함).
  • 후행 구두점도 선행 공백을 억제합니다.
  • 구현된 텍스트의 첫 번째 단어와 대문자 표시를 트리거하는 구두점 뒤에 오는 모든 단어(대소문자 표에 정의된 대로)는 대문자로 표시됩니다. 이는 실현 언어에 대한 특수 대문자 사용 규칙을 준수하는 ucfirst 함수를 사용하여 수행됩니다.

위 규칙의 목적은 템플릿 작성자가 공백이나 문장 부호를 포함해야 하는 위치에 대해 너무 많이 생각하지 않고 가능한 한 자연스럽게 템플릿을 작성할 수 있도록 하는 것입니다. 대부분의 경우 이러한 휴리스틱은 필요한 공백과 문장 부호만 보존합니다(구두점이나 공백의 이스케이프가 필요한 경우 이 기능을 통해 처리되지 않도록 주의하십시오. 템플릿 작성자는 이를 TemplateText 함수 호출로 래핑할 수 있습니다. 그러면 text 어휘소 유형이 할당되어 이러한 종류의 추가 처리를 피할 수 있습니다.).

이 단계의 출력은 단일 템플릿 또는 생성자에 해당하는 텍스트 문자열입니다.

전체 문서 렌더링

Q-id의 추상 콘텐츠에는 여러 생성자가 포함될 수 있으므로 렌더링의 마지막 단계는 각 생성자의 렌더링을 함께 연결하는 것으로 구성됩니다. 이것은 현재 마지막 단계의 출력 문자열을 연결하고 필요한 경우 문자열 사이에 초기 공백을 추가하는 방식으로 매우 간단하게 수행됩니다. 지정된 언어에 대한 렌더러와 연결되지 않은 생성자는 실현에서 단순히 생략됩니다. 이를 통해 전체 실현에 실패하는 대신 해당 언어에 대한 콘텐츠의 부분적 실현이 가능합니다.

기여자 지침

새로운 추상 콘텐츠 작성

AbstractContent 모듈을 편집하여 모든 항목에 대한 새로운 추상 콘텐츠를 생성할 수 있습니다. 각 항목에 대한 추상 콘텐츠는 항목의 Q-id로 키가 지정되는 content 표의 항목입니다.

항목 자체는 지정된 순서로 렌더링될 생성자 목록으로 구성된 테이블입니다. 각 생성자는 필드가 생성자의 내용을 제공하는 테이블입니다. 현재 생성자를 설계하는 방법에 대한 확고한 지침은 없지만 일반적으로 가능한 한 언어에 구애받지 않아야 합니다. 일반적으로 테이블 필드 값은 Q-id와 같은 문자열이어야 하지만 필드에 숫자 또는 부울 값이 포함될 수 있으므로 엄격한 제한은 없습니다. 특히 필드 값은 하위 생성자, 즉 테이블일 수 있습니다.

생성자에 대한 유일한 요구 사항은 _predicate 필드를 포함한다는 것입니다. 해당 필드에는 생성자 유형을 식별하는 문자열이 포함되어야 합니다. 생성자가 렌더링되면 동일한 이름의 해당 렌더러가 조회됩니다.

Constructors 모듈 내에서 특정 유형의 항목에 대한 생성자를 자동으로 생성하는 루아 코드를 작성할 수도 있습니다. 올바른 유형의 생성자를 선택하는 논리는 Constructors 함수에서 발생해야 합니다. 반환 값은 위에서 지정한 대로 생성자 목록(하나로 구성될 수 있음)이어야 합니다.

새 렌더러 생성

이미 정의된 언어에 렌더러를 추가하든, 새 언어에 대한 새 렌더러 모듈을 생성하든, 렌더러는 Module:Sandbox/AbstractWikipedia/Renderers/xx라는 모듈에 있어야 합니다. 여기서 xx는 적절한 언어 코드를 나타냅니다. 언어 중립적인 Module:Sandbox/AbstractWikipedia/Renderers 모듈은 평가 렌더러를 위한 몇 가지 일반적인 유틸리티 함수를 정의합니다.

언어별 렌더러 모듈은 각 필드가 이름을 공유하는 특정 생성자 유형에 대한 렌더러인 테이블(통상 이름은 p)을 내보냅니다(예: Person 렌더러는 Person 생성자를 언어화하기 위한 것입니다). 각 렌더러는 템플릿 그룹 집합(아래에서 설명)로 구성되며 그 중 하나의 이름은 main이어야 합니다. 렌더러가 사용될 때(일반적으로 해당 유형의 생성자를 언어화해야 하기 때문에) main 템플릿 그룹이 언어화됩니다. 다른 템플릿 그룹은 main 템플릿 내에서 그리고 그들 사이에서 하위 템플릿 보간으로 사용할 수 있습니다.

템플릿 그룹은 기본적으로 변형 템플릿 목록입니다. 템플릿 그룹이 평가될 때 전제 조건이 유지되는 목록의 첫 번째 템플릿 변형이 선택되고 언어화됩니다. 이러한 템플릿 변형이 없으면 빈 템플릿이 반환되어 빈 자연어 처리가 반환됩니다.

변형 템플릿은 세 개의 필드가 있는 테이블입니다:

  • 필수 template 필드에는 템플릿 언어 구문을 사용하여 언어화할 실제 템플릿이 포함되어 있습니다(일부 추가 사항은 아래에 설명됨).
  • 선택적 validity 필드는 이 변형이 실현되기 위해 존재해야 하는 생성자의 필드를 나열합니다. 렌더러의 모든 템플릿은 실현된 생성자의 필드에 액세스할 수 있습니다(보간 인수로 사용 가능).
  • 선택적 roles 필드에는 이 변형에 맞는 가능한 문법적 역할이 나열됩니다. 기본적으로 하위 템플릿 또는 해당 생성자의 호출과 함께 사용되는 종속성 레이블에 대한 조건입니다. 해당 레이블이 roles 목록에 나열된 레이블 중 하나에 맞는 경우에만 템플릿이 평가됩니다. 빈 문자열 ""은 레이블이 없는 것과 일치할 수 있습니다.
  • 향후에는 생성자의 필드에서 임의의 조건식을 평가할 수 있도록 추가 conditions 필드가 추가될 수 있습니다.

표준 템플릿 구문과의 차이점

위에서 언급했듯이 구현 시 템플릿 언어 구문 문서에 지정된 것과 비교하여 약간 확장된 구문이 허용됩니다. 이러한 확장에는 다음이 포함됩니다.

  • L-ids(L 다음에 숫자가 옴) 및 Q-ids(Q 다음에 숫자가 옴)는 따옴표 없이 사용할 수 있습니다. 함수에 대한 인수 역할을 할 때 문자열로 변환됩니다. 슬롯 내에서 자체적으로 나타날 때(리터럴 또는 보간된 인수로) 각각 템플릿 함수 Lexeme(L-id)Label(Q-id) 호출에 대한 속기 표기법으로 작동합니다.
  • 마찬가지로 슬롯에 자체적으로 나타나는 숫자(리터럴 또는 보간된 인수)는 Cardinal(number) 템플릿 함수 호출에 대한 속기 역할을 합니다.
  • 보간 인수는 템플릿으로 해석할 수 있는 문자열을 포함할 수 있습니다(슬롯을 포함하므로 { }로 묶인 일부 텍스트). 이 경우 보간 인수는 하위 템플릿(호출 템플릿과 동일한 인수에 액세스할 수 있음)으로 평가됩니다.
  • 마찬가지로 보간 인수에는 템플릿 그룹이 포함될 수 있습니다(위에 정의된 대로). 이것은 특히 렌더러의 정의 내에서 발생합니다. 이 경우 보간은 적절한 템플릿 변형을 선택하고 해당 템플릿을 평가하는 것으로 구성됩니다.
  • 조건 함수에 의한 확장은 이 프로토타입에서 구현되지 않았습니다.
  • 템플릿은 루아 코드 내에서 정의되므로 표준 루아 주석 구문을 사용하여 템플릿 뒤에 주석을 추가할 수 있습니다.

새로운 관계 함수 구현

새 언어에 대한 콘텐츠를 만들 때 새 종속성 관계를 정의하거나 기존 정의를 수정해야 할 수 있습니다. 템플릿에서 사용되는 종속 관계가 자연어화에 영향을 미치려면 해당 관계 함수가 정의되어 있어야 합니다. 이러한 함수는 Module:Sandbox/AbstractWikipedia/Relations의 모든 언어 또는 Module:Sandbox/AbstractWikipedia/Relations/xx의 특정 언어에 대해 정의할 수 있습니다. 여기서 xx는 언어 코드를 나타냅니다.

일반적으로 가능한 한 언어 독립적인 방식으로 관계를 정의하는 것이 좋습니다. 예를 들어, 우리는 많은 언어에 주어-동사 일치가 있다는 것을 알고 있지만 일치하는 정확한 기능은 언어마다 다를 수 있습니다. 기능의 각 조합에 대해 언어별 구현을 정의하는 대신, person, numbergender 기능에 대한 합의를 시행하고 주제에 nominative를 할당하는 언어 독립적인 subj 관계 기능을 정의할 수 있습니다. 이러한 함수는 이러한 일치 기능의 하위 집합만 표시하거나 대소문자 형태가 없는 언어에 대해서도 작동합니다. 관련 없는 작업이 무작동 작업이 되기 때문입니다. 그러나 어떤 경우에는 언어별 구현이 필요합니다. 예를 들어, ergative을 주제에 할당하려면 별도의 언어별 관계 기능 구현이 필요합니다(유사한 언어가 구현을 공유하는 언어 계층 구조로 언어를 그룹화하는 것도 가능할 수 있지만 프로토타입에서는 수행되지 않았습니다.).

NLG 파이프라인이 올바르게 작동하려면 관계 함수가 항상 관계가 작동하는 슬롯에 해당하는 두 개의 입력 인수(sourcetarget)로 정의되어야 합니다. 더욱이 함수의 본문은 관계 적용 순서가 중요하지 않도록 하기 위해 원칙적으로 네 가지 작업만 사용해야 합니다(l 접두어는 어휘소 모듈을 나타냄).

  • verifyPos(slot, part-of-speech): 관련 슬롯이 주어진 것과 통합할 수 있는 품사가 있는 어휘소인지 온전성 검사를 허용합니다. 그러나 대부분의 경우 이 검사는 실제로 너무 제한적이므로 피할 수 있습니다. 원칙적으로 품사는 보다 유연한 유형 검사를 허용하는 유형 계층 구조로 배열될 수 있지만 프로토타입에서는 아직 구현되지 않았습니다.
  • l.unifyFeatures(category-to-unify, source, target): 소스 및 대상 슬롯의 지정된 범주의 기능을 통합합니다.
  • l.unifyFeatures(source-category-to-unify, source, target, target-category-to-unify): 소스 범주의 기능을 대상 범주의 기능과 통합합니다.
  • l.unifyWithFeature(category, slot, feature): 전달된 기능으로 슬롯의 범주에 지정된 기능을 통합합니다. 슬롯에 아직 그러한 범주가 없는 경우 이는 주어진 슬롯의 범주에 새 기능을 할당하는 것과 같습니다.

주어진 함수를 통합할 수 없는 경우 이러한 기능 중 하나라도 실패할 수 있으므로 전체 구현이 실패할 수 있습니다(적절한 오류 메시지 포함).

템플릿 내에서 사용할 새 함수 구현

템플릿 언어의 핵심 부분은 슬롯 내에서 다양한 수의 인수를 사용하여 함수를 호출하는 기능입니다. 이러한 함수의 언어 독립적 구현은 모듈:샌드박스/추상위키백과/함수 모듈 내에서 정의되는 반면 언어별 구현은 Module:Sandbox/AbstractWikipedia/Functions/xx에서 정의됩니다. 여기서 xx는 언어 코드를 나타냅니다. 함수는 내보낸 다른 Scribunto 모듈 함수로 정의됩니다.

슬롯 수준에서 호출되는 함수(다른 함수에 대한 인수로 호출되는 함수와 달리)는 단일 어휘소 또는 어휘소 목록을 반환해야 합니다. lexeme 데이터 유형을 쉽게 구성하기 위해 어휘소 모듈이 편리합니다(l가져옴). 정의된 많은 함수는 Wikidata에서 데이터를 추출합니다. 이를 위해 Wikidata 도우미 모듈(wd가져옴)을 사용할 수 있습니다.

일반적으로 함수가 언어별 위키데이터 어휘소에 접근하거나 일부 언어별 현상을 모델링해야 하는 경우 언어별 구현이 필요합니다. 가능하면 언어 독립적인 함수를 작성하는 것이 좋습니다. 이는 폴백 구현 역할을 할 수 있으며 언어별 구현에 의해 재정의될 수 있습니다.

정의된 함수 중 일부는 제대로 작동하기 위해 시스템에서 필요합니다. 이들은 위에서 설명한 대로 템플릿 언어의 특정 요소에 대해 암시적으로 호출되는 TemplateText, Lexeme, LabelCardinal 함수입니다.

하위 템플릿으로 함수 작성

일반적으로 이러한 모듈에 함수를 작성하려면 루아 프로그래밍 지식이 필요합니다. 그러나 함수 인수가 템플릿 인수에 연결된 하위 템플릿의 단순한 평가인 함수를 정의하는 것이 가능하고 권장됩니다. 예를 들어 QuantifiedNoun 함수가 정의되는 방식은 다음과 같습니다:

 function p.QuantifiedNoun(num, noun)
   return te.evaluateTemplate("{nummod:Cardinal(num)} {root:noun}", { num = num, noun = noun})
 end

사용할 하위 템플릿은 evaluateTemplate 함수의 첫 번째 인수로 제공됩니다(te 접두어는 Functions 모듈 내에서 가져온 TemplateEvaluater 모듈을 나타냄). 이 하위 템플릿은 슬롯, 관계, 함수 호출 및 보간 인수를 포함하여 일반적인 템플릿 언어 구문을 따릅니다. 그러나 이렇게 정의된 템플릿은 evaluateTemplate에 대한 두 번째 인수로 전달된 테이블 내에서 정의된 보간 인수에만 액세스할 수 있습니다(즉, 예에서 { num = num, noun = noun}). 보시다시피 이들은 보간 인수의 이름에 대한 함수 인수의 단순한 바인딩입니다(일반적으로 동일한 이름을 갖지만 필수는 아님). 이러한 종류의 함수 정의를 사용하면 대부분 템플릿 언어 구문을 사용하여 함수를 정의할 수 있으므로 루아에서 프로그래밍하는 방법을 알 필요가 없습니다.