Skip to content

fix: count 질의에 인자 형태 가드가 없어 게이트가 거부하는 질의를 리포트가 검증된 수치로 답한다 #328

Description

@SeoyunL

요약

count 질의에 인자 형태 가드가 없다. 리포트의 validate_query 는 arity 만 보고, 게이트의
classify_query 는 인자가 변수 또는 인용 문자열인지까지 본다. 그래서 게이트가 malformed 로
거부하는 질의를 리포트는 검증된 수치로 렌더한다.

relation/path 분기에는 같은 가드가 이미 들어가 있다. count 만 빠졌다.

재현 (upstream/main c6d359d, Python 3.12 로 실측)

import sys; sys.path.insert(0, '.'); sys.path.insert(0, 'tools')
import run_logic_check as R
from factlog.common import classify_query

facts = [{"subject": "Marie Curie", "relation": "born_in", "object": "Warsaw"},
         {"subject": "Marie Curie", "relation": "born_in", "object": "Poland"}]
ents = {"Marie Curie", "Warsaw", "Poland", "born_in"}

R.validate_query("count(\"Marie Curie\", 'born_in')?", ents, set())
# ([], [])                                              <- 리포트: 통과

classify_query("count(\"Marie Curie\", 'born_in')?", facts)
# (False, 'malformed', 'count arguments must be variables or quoted strings')
#                                                       <- 게이트: 거부

count(Marie Curie, born_in)?(맨 토큰) 도 같다 — 리포트 ([], []) 통과, 게이트 malformed.
arity 위반(count("Marie Curie")?)만 양쪽이 일치한다.

근거

tools/run_logic_check.py:85-89 — arity 만 검사한다.

if predicate == "count":
    # count(subject, relation)? — engine-verified aggregate (see evaluate_queries).
    if len(query_args(line)) != 2:
        errors.append(f"count query must have subject and relation arguments: {line}")
    return errors, warnings

대조 — 같은 파일의 relation/path 분기에는 인자 형태 가드가 있고, factlog/common.py
classify_querycount 에도 _is_valid_arg 를 적용한다.

숫자가 왜 틀리는지는 evaluate_queries(:139-150)의 count 분기가 보여준다.

subj_const = subj_q.startswith('"') and subj_q.endswith('"')
rel_const  = rel_q.startswith('"') and rel_q.endswith('"')
objects = {f["object"] for f in facts
           if (not subj_const or f["subject"] == subj)
           and (not rel_const or f["relation"] == rel)}

인용되지 않은 인자는 와일드카드로 취급된다. 그래서 'born_in'(작은따옴표)은 관계 필터로
동작하지 않고, 그 subject 의 모든 관계에 걸친 서로 다른 객체 수가 나온다. 사용자가 의도한
"born_in 의 값 개수" 가 아니다.

영향

  • 심각도 중간. 크래시가 아니라 틀린 수를 검증된 값으로 보고한다. 집계는 사용자가 검산
    하지 않는 대표적인 출력이다.
  • 게이트가 거부하는 줄을 리포트가 답하므로, 두 경로 중 무엇을 믿어야 하는지가 갈린다
    (리포트/게이트 발산).

제안

validate_querycount 분기에 relation/path 와 동일한 인자 형태 가드를 넣어, 변수도
인용 문자열도 아닌 인자를 malformed 로 거부한다. 판정 함수를 게이트와 공유하면 세 번째 분기
에서 같은 누락이 재발하지 않는다.

수용 기준

  • count("S", 'r')? · count(S, r)? 형태를 리포트가 malformed 로 거부한다.
  • 같은 줄에 대해 리포트와 게이트의 판정이 일치한다.
  • 정상 형태(count("S", "r")?, count(S, R)?)의 기존 결과 불변(회귀 없음).
  • arity 위반의 기존 메시지 불변.
  • 리포트/게이트 파리티를 count 에 대해 고정하는 테스트.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions