diff --git a/.gitignore b/.gitignore index 0385322..e8a8f1a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ /.idea *.xml /generate_dataset/build_labels/instance_funcs/llm_instance_datadir +.idea/workspace.xml diff --git a/__pycache__/operators_concepts.cpython-311.pyc b/__pycache__/operators_concepts.cpython-311.pyc new file mode 100644 index 0000000..b24803e Binary files /dev/null and b/__pycache__/operators_concepts.cpython-311.pyc differ diff --git a/__pycache__/operators_concepts.cpython-39.pyc b/__pycache__/operators_concepts.cpython-39.pyc new file mode 100644 index 0000000..a303121 Binary files /dev/null and b/__pycache__/operators_concepts.cpython-39.pyc differ diff --git a/generate_dataset/ad_hoc_(can_ignore)/concepts.json b/generate_dataset/ad_hoc_(can_ignore)/concepts.json new file mode 100644 index 0000000..f28e7d4 --- /dev/null +++ b/generate_dataset/ad_hoc_(can_ignore)/concepts.json @@ -0,0 +1,25 @@ +{ + "Curve": "曲线", + "Conicsection": "\\in Curve 圆锥曲线", + "Line": "\\in Curve 直线", + "Linesegment": "\\in Curve 线段", + "Ray": "\\in Curve 射线", + "Hyperbola": "\\in ConicSection 双曲线", + "Circle": "\\in ConicSection 圆", + "Parabola": "\\in ConicSection 抛物线", + "Ellipse": "\\in ConicSection 椭圆", + "Point": "二维坐标系中的点", + "Origin": "\\in Point 二维坐标系的原点", + "Axis": "二维坐标系中的坐标轴", + "Xaxis": "\\in axis 二维坐标系中的横坐标", + "Yaxis": "\\in axis 二维坐标系中的纵坐标", + "Vector": "二维向量", + "Angle": "角", + "Number": "数", + "Real": "\\in Number 实数", + "Rad": "弧度", + "Degree": "度", + "Pi": "圆周率", + "Pm": "±", + "Triangle": "三角形" +} \ No newline at end of file diff --git a/generate_dataset/ad_hoc_(can_ignore)/operators.json b/generate_dataset/ad_hoc_(can_ignore)/operators.json new file mode 100644 index 0000000..40398f4 --- /dev/null +++ b/generate_dataset/ad_hoc_(can_ignore)/operators.json @@ -0,0 +1,92 @@ +{ + "Coordinate": "Coordinate(p: Point) -> (Number, Number):二维坐标系中点p的坐标。", + "Xcoordinate": "XCoordinate(p: Point) -> Number:二维坐标系中点p的横坐标。", + "Ycoordinate": "YCoordinate(p: Point) -> Number:二维坐标系中点p的纵坐标。", + "Locusequation": "LocusEquation(p: Point) -> Expression:点p的轨迹方程。", + "Locus": "Locus(p: Point) -> Curve:点p的轨迹。", + "Quadrant": "Quadrant(p: Point) -> Number:点p所在的象限。", + "Focus": "Focus(c: ConicSection) -> Union[Set[point], Point]:圆锥曲线c的焦点,如果有多个焦点则返回集合,否则返回该点。", + "Rightfocus": "RightFocus(c: ConicSection) -> Point:圆锥曲线c的右焦点。", + "Leftfocus": "LeftFocus(c: ConicSection) -> Point:圆锥曲线c的左焦点。", + "Lowerfocus": "LowerFocus(c: ConicSection) -> Point:圆锥曲线c的下焦点。", + "Upperfocus": "UpperFocus(c: ConicSection) -> Point:圆锥曲线c的上焦点。", + "Focallength": "FocalLength(c: ConicSection) -> Number:圆锥曲线c的焦距。", + "Halffocallength": "HalfFocalLength(c: ConicSection) -> Number:圆锥曲线c的半焦距。", + "Symmetryaxis": "SymmetryAxis(c: ConicSection) -> Axis:圆锥曲线c的对称轴。", + "Eccentricity": "Eccentricity(c: ConicSection) -> Number:圆锥曲线c的离心率。", + "Vertex": "Vertex(c: ConicSection) -> Union[Set[Point], Point]:圆锥曲线c的顶点,如果有多个顶点则返回集合,否则返回该点。", + "Uppervertex": "UpperVertex(c: Union[Ellipse,Hyperbola]) -> Point:椭圆或双曲线c的上顶点。", + "Lowervertex": "LowerVertex(c: Union[Ellipse,Hyperbola]) -> Point:椭圆或双曲线c的下顶点。", + "Leftvertex": "LeftVertex(c: Union[Ellipse, Hyperbola]) -> Point:椭圆或双曲线c的左顶点。", + "Rightvertex": "RightVertex(c: Union[Ellipse, Hyperbola]) -> Point:椭圆或双曲线c的右顶点。", + "Directrix": "Directrix(c: ConicSection) -> Union[Set[Line], Line]:圆锥曲线c的准线,如果有多条准线则返回集合,否则返回该条准线。", + "Leftdirectrix": "LeftDirectrix(c: ConicSection) -> Line:圆锥曲线c的左准线。", + "Rightdirectrix": "RightDirectrix(c: ConicSection) -> Line:圆锥曲线c的右准线。", + "Majoraxis": "MajorAxis(g: Ellipse) -> LineSegment:椭圆g的长轴。", + "Minoraxis": "MinorAxis(g: Ellipse) -> LineSegment:椭圆g的短轴。", + "Realaxis": "RealAxis(c: Hyperbola) -> LineSegment:双曲线c的实轴。", + "Imageinaryaxis": "ImageinaryAxis(c: Hyperbola) -> LineSegment:双曲线c的虚轴。", + "Leftpart": "LeftPart(c: Hyperbola) -> Curve:双曲线c的左支部分。", + "Rightpart": "RightPart(c: Hyperbola) -> Curve:双曲线c的右支部分。", + "Asymptote": "Asymptote(c: Hyperbola) -> Set[Line]:双曲线c的两条渐近线。", + "Diameter": "Diameter(c: Circle) -> Number:圆c的直径。", + "Radius": "Radius(c: Circle) -> Number:圆c的半径。", + "Perimeter": "Perimeter(c: Union[Circle, Ellipse]) -> Number:圆c的周长。", + "Center": "Center(c: Union[Circle, Ellipse]) -> Point:圆或椭圆c的中心点。", + "Expression": "Expression(c: Curve):曲线c的方程。", + "Lineof": "LineOf(p1: Point, p2: Point) -> Line:穿过p1、p2两点的一条直线。", + "Slope": "Slope(l: Line) -> Number:直线l的斜率。", + "Inclination": "Inclination(l: Line) -> Number:直线l的倾斜角。", + "Intercept": "Intercept(l: Line, a: Union[xAxis, yAxis]) -> Number:直线l在坐标轴上的截距。", + "Linesegmentof": "LineSegmentOf(p1: Point, p2: Point) -> LineSegment:连接p1、p2两点的线段。", + "Length": "Length(l: LineSegment) -> Number:线段l的长度。", + "Midpoint": "MidPoint(l: LineSegment) -> Point:线段l的中点。", + "Overlappingline": "OverlappingLine(l: LineSegment) -> Line:线段l所在的直线。", + "Perpendicularbisector": "PerpendicularBisector(l: LineSegment) -> Line:线段l的垂直平分线。", + "Endpoint": "Endpoint(l: Union[LineSegment, Ray]) -> Union[Set[Point], Point]:线段或射线l的端点,如果有多个端点则返回集合,否则返回该点。", + "Projection": "Projection(p: Point, l: Union[Line, Axis]) -> Point:点p在l上的投影。", + "Interceptchord": "InterceptChord(l: Line, c: ConicSection) -> LineSegment:直线l被圆锥曲线c截取的线段。", + "Triangleof": "TriangleOf(p1: Point, p2: Point, p3: Point) -> Triangle:以p1、p2、p3为顶点的三角形。", + "Inscribedcircle": "InscribedCircle(t: Triangle) -> Circle:三角形t的内切圆。", + "Circumcircle": "CircumCircle(t: Triangle) -> Circle:三角形t的外接圆。", + "Incenter": "Incenter(t: Triangle) -> Point:三角形t的内心。", + "Orthocenter": "Orthocenter(t: Triangle) -> Point:三角形t的垂心。", + "Circumcenter": "Circumcenter(t: Triangle) -> Point:三角形t的外心。", + "Angleof": "AngleOf(p1: Point, p2: Point, p3: Point) -> Number:以p2为顶点的∠p1p2p3的角度值。", + "Vectorof": "VectorOf(p1: Point, p2: Point) -> Vector:由点p1指向点p2的向量。", + "Dotproduct": "DotProduct(v1: Vector, v2: Vector) -> Number:向量v1与向量v2的点积。", + "Numintersection": "NumIntersection(a: Union[Axis, Curve], b: Union[Axis, Curve]) -> Number:a与b的交点的数量。", + "Intersection": "Intersection(a: Union[Axis, Curve], b: Union[Axis, Curve]) -> Union[Set[point], Point]:a与b的交点,如果有多个交点则返回集合,否则返回该点。", + "Footpoint": "FootPoint(l1: Union[Line, LineSegment], l2: Union[Line, LineSegment]) -> Point:线l1与线l2互相垂直,获取其垂足。", + "Distance": "Distance(a: Union[Point, Line], b: Union[Point, Line]) -> Number:a与b之间的距离。", + "Area": "Area(c: Union[Circle, Ellipse, Triangle]) -> Number:c的面积。", + "Tangentpoint": "TangentPoint(l: Line, c: Circle) -> Point:直线l与曲线c相切于c上的一点。", + "Tangentofpoint": "TangentOfPoint(p: Point, c: Curve) -> Line:过点p作出的曲线c的切线。", + "Tangentonpoint": "TangentOnPoint(p: Point, c: Curve) -> Line:过曲线c上的一点p作曲线c的切线。", + "Oneof": "OneOf(s: Set[T]) -> T:获取集合s中的一个元素。", + "Abs": "Abs(n: Union[Number, LineSegment]) -> Number:n的绝对值。", + "Lg": "lg(n: Number) -> Number:数n的log值。", + "Interreciprocal": "InterReciprocal(n: Number) -> Number:数n的倒数。", + "Sqrt": "sqrt(n: Number) -> Number:数n的平方根。", + "Max": "Max(n: Number) -> Number:变量n的最大值。", + "Min": "Min(n: Number) -> Number:变量n的最小值。", + "Range": "Range(n: Number) -> (Number, Number):变量n的取值范围。", + "Whenmin": "WhenMin(n: Number):当变量n取最小值时。", + "Whenmax": "WhenMax(n: Number):当变量n取最大值时。", + "Applyunit": "ApplyUnit(n: Number, u: Union[degree, rad]):以n数值,u为单位的值。", + "In": "In(n: Number, (r1: Number, r2: Number)):变量n的值位于区间(r1,r2)。", + "Between": "Between(p1: Point, p2: Point, p3: Point):点p1位于点p2和点p3之间。", + "Isintersect": "IsIntersect(a: Union[Axis, Curve], b: Union[axis, Curve]):a与b相交。", + "Isperpendicular": "IsPerpendicular(l1: Union[Line, LineSegment, xAxis, yAxis], l2: Union[Line, LineSegment, xAxis, yAxis]):l1与l2互相垂直。", + "Isparallel": "IsParallel(l1: Union[Line, LineSegment, xAxis, yAxis], l2: Union[Line, LineSegment, xAxis, yAxis]):l1与l2互相平行。", + "Isdiameter": "IsDiameter(l: LineSegment, c: Circle):线段l是圆c的直径。", + "IschordOf": "IsChordOf(l: LineSegment, c: ConicSection):线段l是圆锥曲线c的弦。", + "Istangent": "IsTangent(l: Line, c: ConicSection):直线l是圆锥曲线c的切线。", + "Isinscribedcircle": "IsInscribedCircle(c: Circle, t: Triangle):圆c是三角形t的内切圆。", + "Iscircumcircle": "IsCircumCircle(c: Circle, t: Triangle):圆c是三角形t的外接圆。", + "Isintangent": "IsInTangent(c1: Circle, c2: Circle):圆c1与圆c2内切。", + "Isouttangent": "IsOutTangent(c1: Circle, c2: Circle):圆c1与圆c2外切。", + "Pointoncurve": "PointOnCurve(p: Point, c: Union[Axis, Curve]):点p在c上。", + "And": "And(a: Assersion, b: Assertion):断言逻辑表达式a与b同时成立。", + "Negation": "Negation(a: Assertion):断言逻辑表达式a不成立。" +} \ No newline at end of file diff --git a/generate_dataset/ad_hoc_(can_ignore)/problems/_filter.py b/generate_dataset/ad_hoc_(can_ignore)/problems/_filter.py new file mode 100644 index 0000000..65b3b8d --- /dev/null +++ b/generate_dataset/ad_hoc_(can_ignore)/problems/_filter.py @@ -0,0 +1,23 @@ +# 其中一个小实验进行的数据过滤,但是合正常流程和最终的实验无关 + +import json + +# 读取原始数据 +with open(r"D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output" + r"\merge_tuples\conic10k_output_1_problem_new.json", "r", encoding="utf-8") as f: + datas = json.load(f) + +res = [] +for data in datas: + declaration = data["Declarations"] + if "Triangle" in declaration: # hack(zcl): 这个是因为cfg里不小心新增了Triangle这个concept,conic10k里没有, + # 但因为已经生成自然语言问题了,就先这样特殊处理了 + continue + else: + res.append(data) + +with open( + r"D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output" + r"\synthetic_datas.json", + "w", encoding="utf-8") as f: + json.dump(res, f, indent=4, ensure_ascii=False) diff --git a/generate_dataset/ad_hoc_(can_ignore)/problems/filter.py b/generate_dataset/ad_hoc_(can_ignore)/problems/filter.py new file mode 100644 index 0000000..ade5955 --- /dev/null +++ b/generate_dataset/ad_hoc_(can_ignore)/problems/filter.py @@ -0,0 +1,17 @@ +import json +import random + +# 读取原始数据 +with open(r"D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output\merge_tuples\conic10k_output_1_problem_new.json", "r", encoding="utf-8") as f: + datas = json.load(f) + +res = [] +for data in datas: + declaratiosn = data["Declarations"] + if "Triangle" in declaratiosn: + continue + else: + res.append(data) + +with open(r"D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output\synthetic_datas.json", "w", encoding="utf-8") as f: + json.dump(res, f, indent=4, ensure_ascii=False) \ No newline at end of file diff --git a/generate_dataset/ad_hoc_(can_ignore)/problems/sample_datas.py b/generate_dataset/ad_hoc_(can_ignore)/problems/sample_datas.py new file mode 100644 index 0000000..19c7527 --- /dev/null +++ b/generate_dataset/ad_hoc_(can_ignore)/problems/sample_datas.py @@ -0,0 +1,31 @@ +import json +import random + +# 读取原始数据 +with open(r"D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output\synthetic_datas.json", "r", encoding="utf-8") as f: + data = json.load(f) + +assert len(data) == 10456, f"数据数量为 {len(data)},不是 16500" + +# 分层参数设置 +num_layers = 8 # 每层 500 条 +layer_size = 1307 +layers = [data[i * layer_size:(i + 1) * layer_size] for i in range(num_layers)] + +# 需要的总样本数 +sample_sizes = [2614, 5228, 7842, 10456] + +# 每层采样比例 = 样本数 / 总数据数 +def stratified_sampling(layers, total_samples, seed=42): + random.seed(seed) + samples = [] + per_layer = total_samples // len(layers) # 均匀抽样数量 + for layer in layers: + samples.extend(random.sample(layer, per_layer)) + return samples + +# 按不同目标数量生成样本 +for size in sample_sizes: + sampled = stratified_sampling(layers, size) + with open(f"D:\\桌面\\6023\\generate_dataset\\semantic_parsing-q_upload_change\\generate_dataset\\assertions_output\\sample_{size}.json", "w", encoding="utf-8") as f: + json.dump(sampled, f, ensure_ascii=False, indent=2) diff --git a/generate_dataset/ad_hoc_(can_ignore)/random_merge.py b/generate_dataset/ad_hoc_(can_ignore)/random_merge.py new file mode 100644 index 0000000..57f35aa --- /dev/null +++ b/generate_dataset/ad_hoc_(can_ignore)/random_merge.py @@ -0,0 +1,162 @@ +# hack: # fixme: 这个文件本身应当通过START ← Assertions + Assertions ← Assertion Assertions来处理 +# 这个文件只能算是特殊处理的方案。但既然已经写了就放在这里 + +# 随机组合assertions,得到一个问题 +import random +import json + + +def preprocess_data(data: list[dict]) -> list[dict]: + """预处理数据,过滤掉declarations或facts为None的元素""" + return [elem for elem in data if + elem.get('declarations') is not None and elem.get('facts') is not None and elem.get('facts').count('(') < 3] + + +def parse_declarations(decl_str: str) -> dict[str, str]: + """解析declarations字符串为字典,过滤数字声明并标准化类型名称""" + if decl_str is None: + return {} + decl_str = decl_str.strip() + if not decl_str: + return {} + decls = {} + parts = [p.strip() for p in decl_str.split(';') if p.strip()] + for part in parts: + try: + var, typ = part.split(':') + var = var.strip() + typ = typ.strip() + # 过滤掉纯数字的变量名 + if var.isdigit(): + continue + elif var.startswith('-') and var.lstrip('-').isdigit(): + continue + elif var.lower() == "true" or var.lower() == "false": + continue + # 标准化类型名称:首字母大写,其余小写 + typ = typ.capitalize() + decls[var] = typ + except ValueError: + continue # 忽略格式错误的声明 + return decls + + +def check_conflict(decls1: dict[str, str], decls2: dict[str, str]) -> bool: + """检查两个declarations字典是否有冲突""" + common_vars = set(decls1.keys()) & set(decls2.keys()) + for var in common_vars: + if decls1[var] != decls2[var]: + return True + return False + + +def combine_elements(elements: list[dict]) -> tuple[dict[str, str] | None, list[str] | None]: + """合并多个元素的declarations和facts,返回合并后的declarations和facts列表""" + combined_decls = {} + facts = [] + for elem in elements: + decls = parse_declarations(elem.get('declarations')) + # 检查冲突 + if check_conflict(combined_decls, decls): + return None, None + combined_decls.update(decls) + fact = elem.get('facts') + if fact is not None: + facts.append(fact) + return combined_decls, facts + + +def transform_fact_to_question(fact: str) -> tuple[str, str | None] | None: + """ + 将 fact 的右式替换为 '?',并返回替换后的 fact 和被替换的右式变量(如果有)。 + 例如: + - 输入 "DotProduct(q, e) = -8" → 返回 ("DotProduct(q, e) = ?", None) + - 输入 "MajorAxis(k) = o" → 返回 ("MajorAxis(k) = ?", "o") + """ + if '=' not in fact: + return None # 忽略格式错误的 fact + left, right = fact.split('=', 1) + right = right.strip() + + # 检查右式是否是变量(由字母组成,不含运算符或括号) + right_var = right if right.isalpha() else None + transformed_fact = f"{left.strip()} = ?" + return transformed_fact, right_var + + +def transform_combination(combination: dict) -> dict: + """ + 对单个组合进行转换: + 1. 随机选择一个 fact,将其右式替换为 '?' + 2. 如果被替换的右式是一个变量,则从 declarations 中移除它 + """ + facts = combination["facts"] + if not facts: + return combination # 无 facts 可转换 + + # 随机选择一个 fact 进行转换 + selected_index = random.randint(0, len(facts) - 1) + selected_fact = facts[selected_index] + + # 替换右式为 '?' + transformed_fact, right_var = transform_fact_to_question(selected_fact) + if transformed_fact is None: + return combination # 转换失败 + + # 更新 facts + new_facts = facts.copy() + new_facts[selected_index] = transformed_fact + + # 更新 declarations(如果右式是变量) + new_declarations = combination["declarations"].copy() + if right_var is not None and right_var in new_declarations: + del new_declarations[right_var] + + return { + "id": combination["id"], + "declarations": new_declarations, + "facts": new_facts + } + + +def find_valid_combinations(data: list[dict], min_size=2, max_size=5, max_attempts=5000, max_tuples=10) -> list[dict]: + """随机寻找有效的元素组合,确保declarations不超过8个""" + valid_combinations = [] + attempts = 0 + data = preprocess_data(data) # 预处理数据 + while attempts < max_attempts and len(valid_combinations) < max_tuples: + attempts += 1 + k = random.randint(min_size, max_size) + if k > len(data): + continue + selected = random.sample(data, k) + combined_decls, combined_facts = combine_elements(selected) + if combined_decls is not None and combined_facts and len(combined_decls) <= 8: + valid_combinations.append({ + "id": len(valid_combinations) + 1, + "declarations": combined_decls, + "facts": combined_facts + }) + return valid_combinations + + +def main(): + file = open( + r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output\assertions' + r'\conic10k_output_1.jsonl', + 'r', encoding='utf-8') + data = json.load(file) + valid_combinations = find_valid_combinations(data, max_tuples=100000) + + # 对每个组合进行转换(随机选择一个 fact 替换为 '?') + transformed_combinations = [transform_combination(comb) for comb in valid_combinations] + + new_file = open( + r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output' + r'\merge_assertions\conic10k_output_1_new.json', + 'w', encoding='utf-8') + json.dump(transformed_combinations, new_file, indent=4, ensure_ascii=False) + + +if __name__ == "__main__": + main() diff --git a/generate_dataset/build_labels/instance_funcs/_existed_instance_provider.py b/generate_dataset/build_labels/instance_funcs/_existed_instance_provider.py index 97a1a45..525a56d 100644 --- a/generate_dataset/build_labels/instance_funcs/_existed_instance_provider.py +++ b/generate_dataset/build_labels/instance_funcs/_existed_instance_provider.py @@ -1,4 +1,5 @@ import random +import string from mimesis import Generic, BaseProvider, BaseDataProvider from mimesis.locales import Locale @@ -761,6 +762,24 @@ def category_event(): return random.choice(category_event) +class Capital_Provider(FakerProvider): + @staticmethod + def capital() -> str: + random_letter = chr(random.choice([random.randint(65, 90), random.randint(97, 122)])) + return random_letter + +class Capitals_Provider(FakerProvider): + @staticmethod + def capitals() -> str: + random_letters = ', '.join(random.sample(string.ascii_uppercase, 2)) + return random_letters + +class Number_Provider(FakerProvider): + @staticmethod + def number() -> str: + random_number = random.randint(-100, 100) + return random_number + def __get_existed_provider_from_mimesis(mimesis_generator) -> list[BaseProvider]: providers = [] @@ -812,6 +831,9 @@ def _get_existed_generator_faker(language='EN') -> dict[str, callable]: fake.add_provider(Location_Provider) fake.add_provider(Event_Attribute_Provider) fake.add_provider(Reminder_Provider) + fake.add_provider(Capital_Provider) + fake.add_provider(Capitals_Provider) + fake.add_provider(Number_Provider) funcs = {fn.replace('_', ' '): fake.__getattr__(fn) for fn in dir(fake.factories[0]) if not fn.startswith('_')} # 正常情况len(factories)就是==1的 return funcs diff --git a/generate_dataset/build_labels/instance_funcs/_instance_prompt.py b/generate_dataset/build_labels/instance_funcs/_instance_prompt.py index b839b28..8543cb6 100644 --- a/generate_dataset/build_labels/instance_funcs/_instance_prompt.py +++ b/generate_dataset/build_labels/instance_funcs/_instance_prompt.py @@ -1,18 +1,30 @@ def _concept_instance_prompt(concept: str) -> str: - instruct = '''You are an instantiation generator, when l give you a concept like "date time", "common weather adjective", "weather attribute", etc. you need to give some detailed example instances about it. -The "common weather adjective" represent want to get common weather conditions adjective such as rainy, snowy, sunny and so on. "date time" indicates the time that want to get the weather, which can be vague like "tonight, tomorrow" or precise like "this Monday, next Friday, March 5" and so on. -Don't give the process or any extra words, just return 10 various instances. Again, no extra words and no extra punctuations. + # ====topv2提示词======= +# instruct = '''You are an instantiation generator, when l give you a concept like "date time", "common weather adjective", "weather attribute", etc. you need to give some detailed example instances about it. +# The "common weather adjective" represent want to get common weather conditions adjective such as rainy, snowy, sunny and so on. "date time" indicates the time that want to get the weather, which can be vague like "tonight, tomorrow" or precise like "this Monday, next Friday, March 5" and so on. +# Don't give the process or any extra words, just return 10 various instances. Again, no extra words and no extra punctuations. -######### examples ########### -Question: Please randomly give an instance about "date time" -Answer: ["Tonight", "today", "15 May", "May 2024", "2020.3.15", ...] +# ######### examples ########### +# Question: Please randomly give an instance about "date time" +# Answer: ["Tonight", "today", "15 May", "May 2024", "2020.3.15", ...] -Question: Please randomly give an instance about "location" -Answer: ["sydney", "China", ...] +# Question: Please randomly give an instance about "location" +# Answer: ["sydney", "China", ...] -Question: Please randomly give an instance about "common weather adjective" -Answer: ["snowy", "sunny", "cloudy", ...] +# Question: Please randomly give an instance about "common weather adjective" +# Answer: ["snowy", "sunny", "cloudy", ...] -Question: Please randomly give an instance about "{}"\nAnswer:''' +# Question: Please randomly give an instance about "{}"\nAnswer:''' + + # ====conic10k提示词======= # todo: 此刻的替代品是"无法顾名思义的concept,就单独提供一个provider" + instruct = '''You are an example generator. When I give you a concept "EXPRESSION", you need to give some specific examples about it. +"EXPRESSION" means the equation of a curve in a rectangular coordinate system. +Do not give the process or any extra text, just return 10 different examples. Also, do not use extra text and punctuation. + +######### Example ########### +Question: Please give a random example about "EXPRESSION" +Answer: ["x-2*y+6=0", "(x + 2)^2 + (y + 2)^2 = 1", "y=4/3*x", "-y^2/b^2 + x^2/a^2 = 1", "x^2 = 2*(p*y)", "x^2/3 + y^2/2 = 1", ...] + +Question: Please give a random example about "{}"\nAnswer: ''' return instruct.format(concept) \ No newline at end of file diff --git a/generate_dataset/build_labels/instance_funcs/_llm_instance_provider.py b/generate_dataset/build_labels/instance_funcs/_llm_instance_provider.py index 6e7dbc8..7c39089 100644 --- a/generate_dataset/build_labels/instance_funcs/_llm_instance_provider.py +++ b/generate_dataset/build_labels/instance_funcs/_llm_instance_provider.py @@ -4,9 +4,12 @@ from collections import defaultdict from pathlib import Path +import sys +sys.path.append(r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset') + from mimesis.providers.base import BaseProvider -from ._instance_prompt import _concept_instance_prompt -from generate_dataset.gen_utils.access_llm import async_query_gpt +from build_labels.instance_funcs._instance_prompt import _concept_instance_prompt +from gen_utils.access_llm import async_query_gpt _DATADIR = Path(__file__).parent / 'llm_instance_datadir' if not os.path.exists(_DATADIR): @@ -48,7 +51,8 @@ def _random_choice_and_delete(candidate: list[str]) -> str: async def _llm_concept_instances(concept_name: str) -> list[str]: - prompt = _concept_instance_prompt(concept_name) + prompt = _concept_instance_prompt(concept_name) # todo(lbq): 如果允许传入concept的描述会更好一些。此刻的替代品是无法顾名思义 + # 的concept,就单独提供一个provider来干。https://github.com/msg-bq/semantic_parsing/pull/24/files#r2103713390 while True: # hack: 这里给个最大的try_cnt会好一点 try: concept_instances_text = await async_query_gpt(prompt, temperature=0.3) diff --git a/generate_dataset/build_labels/random_cfg_deriver.py b/generate_dataset/build_labels/random_cfg_deriver.py index 9a7e9f1..9230c05 100644 --- a/generate_dataset/build_labels/random_cfg_deriver.py +++ b/generate_dataset/build_labels/random_cfg_deriver.py @@ -101,7 +101,7 @@ def _avoid_spurious_non_terminal_symbol(terminal_symbol): if not variable_references: break - random_variable = random.choice(variable_references) # hack: 这个地方酌情优化,未经优化的random会导致大量重复 + random_variable = random.choice(variable_references) # XXX: 这个地方酌情优化,未经优化的random会导致大量重复 # random_production = random.choice(grammar.variable_dict[random_variable.name].rules) random_production = _roulette_choice_rule(grammar.variable_dict[random_variable.name].rules) @@ -126,19 +126,20 @@ def _avoid_spurious_non_terminal_symbol(terminal_symbol): return updated_string -async def generate_expressions(n: int) -> list: +# async def generate_expressions(n: int) -> list: +async def generate_expressions(n: int, dataset_file: str | None = None) -> list: """ :param n: 生成的数量 :return 断言逻辑表示的表达式 """ - if len(sys.argv) != 2: + if len(sys.argv) == 1 and dataset_file is None: print('Required usage: python3 random_cfg_deriver.py ') print('Where filename is the name of a .cfg file.') exit() # Collect command line argument - filename = sys.argv[1] + filename = sys.argv[1] if len(sys.argv) == 2 else dataset_file # Parse file into variable objects for our grammar print('Loading grammar from "{}"...'.format(filename)) diff --git a/generate_dataset/build_labels/translate_format.py b/generate_dataset/build_labels/translate_format.py index 24469e6..740c7fe 100644 --- a/generate_dataset/build_labels/translate_format.py +++ b/generate_dataset/build_labels/translate_format.py @@ -1,6 +1,6 @@ # 本文件用于将断言语法的结果,输出为特定下游任务所需的格式 -from generate_dataset.generate_natural_language.dataset_class import CustomDataset -from generate_dataset.modeling import FACT_TYPE, Assertion, Formula, Term, BaseIndividual +from generate_natural_language.dataset_class import CustomDataset +from modeling import FACT_TYPE, Assertion, Formula, Term, BaseIndividual def _translate_format_topv2(al_expressions: list[Assertion | Formula]) -> list[str]: diff --git a/generate_dataset/gen_utils/access_llm.py b/generate_dataset/gen_utils/access_llm.py index 0b9746b..2683ddd 100644 --- a/generate_dataset/gen_utils/access_llm.py +++ b/generate_dataset/gen_utils/access_llm.py @@ -1,22 +1,24 @@ import time -from openai import AsyncOpenAI, OpenAI, NOT_GIVEN +from openai import AsyncOpenAI, OpenAI -# model = "deepseek-chat" -# api_key = 'sk-bd3ccb0c1ceb43e0b8210a90657b7bb4' -# aclient_gpt = AsyncOpenAI(api_key=api_key, -# base_url="https://api.deepseek.com/") +model = "deepseek-chat" +api_key = 'sk-bd3ccb0c1ceb43e0b8210a90657b7bb4' +aclient_gpt = AsyncOpenAI(api_key=api_key, + base_url="https://api.deepseek.com/") # client_gpt = OpenAI(api_key=api_key, # base_url="https://api.deepseek.com/") # deepseek-chat -model = "gpt-4o-mini" -api_key = 'sk-CrQb5MFkrdZafRMnoNTfpNEyRiRJrzjIXOn3iF0BxQuB0F0M' -aclient_gpt = AsyncOpenAI(api_key=api_key, - base_url="https://api.chatanywhere.tech/v1") -client_gpt = OpenAI(api_key=api_key, - base_url="https://api.chatanywhere.tech/v1") +# model = "gpt-4o-mini" +# api_key = 'sk-56a4ejBaNLcRbTiZfnbIX6L6i3lDzuCdscWRhPO1TR5tQfnJ' +# aclient_gpt = AsyncOpenAI(api_key=api_key, +# base_url="https://api.chatanywhere.tech/v1") +# client_gpt = OpenAI(api_key=api_key, +# base_url="https://api.chatanywhere.tech/v1") + + #chatgpt @@ -35,7 +37,17 @@ # base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", # ) -async def async_query_gpt(user_prompt: str, model=model, temperature=NOT_GIVEN) -> str: +# client = OpenAI(api_key="6137bd4d-1a18-4159-ad53-8dded07d3e1d", base_url="https://ark.cn-beijing.volces.com/api/v3") +# model = "deepseek-v3-241226" + +async def async_query_gpt(user_prompt: str, model=model, temperature=0.3) -> str: + # response = await client.chat.completions.create( + # model=model, + # messages=[ + # {"role": "system", "content": "You are a helpful assistant"}, + # {"role": "user", "content": user_prompt}, + # ], + # ) response = await aclient_gpt.chat.completions.create( model=model, messages=[ @@ -48,7 +60,7 @@ async def async_query_gpt(user_prompt: str, model=model, temperature=NOT_GIVEN) return response.choices[0].message.content -def query_gpt(user_prompt: str, model=model, temperature=NOT_GIVEN) -> str: +def query_gpt(user_prompt: str, model=model, temperature=0.3) -> str: if isinstance(user_prompt, str): prompt = [{"role": "user", "content": user_prompt}] else: @@ -58,7 +70,7 @@ def query_gpt(user_prompt: str, model=model, temperature=NOT_GIVEN) -> str: while try_call: try_call -= 1 try: - response = client_gpt.chat.completions.create( + response = client.chat.completions.create( # fixme: conic分支后有报错,后期处理下 model=model, messages=prompt, temperature=temperature diff --git a/generate_dataset/gen_utils/call_vllm.py b/generate_dataset/gen_utils/call_vllm.py new file mode 100644 index 0000000..fea5516 --- /dev/null +++ b/generate_dataset/gen_utils/call_vllm.py @@ -0,0 +1,121 @@ +# 将组合的assertions转换成数学问题 + +import json +import re +from openai import OpenAI + +instruction = '''You are a language expert. When I give you a formal text of assertion logic and related assertion logic knowledge, you need to convert it into a mathematical problem. + +Assertion logic knowledge: +##### Concept ##### +{} + +##### Function ##### +{} +''' + +input_prompt = '''There are some examples. +##### Examples ##### +Input assertion logic: +Declarations: "n: Linesegment; m: Hyperbola; y: Conicsection" +Facts: "Abs(n) = -47; Expression(RightPart(m)) = y = 3x + 2" +Query: "UpperFocus(y) = ?" + +Output mathematical problem: +"线段n的长为-47,双曲线m右部分的方程为y = 3x + 2,对于圆锥曲线y,其上焦点为什么?" + + +Input assertion logic: +Declarations: "i: Ellipse; g: Conicsection" +Facts: "Area(g) = 75" +Query: "OverlappingLine(MinorAxis(i)) = ?" + +Output mathematical problem: +"圆锥曲线g的面积为75,对于椭圆i,其短轴所在的直线为什么?" + + +Now please convert the following assertion logic into a mathematical problem. +Input assertion logic: +Declarations: {} +Facts: {} +Query: {} + +Output mathematical problem: +''' + + +def find_concepts(concepts, concepts_name): + concept_prompt = [] + for index, concept in enumerate(concepts_name): + if concept in concepts.keys(): + concept_prompt.append(f"{index + 1}. {concept.capitalize()}: {concepts[concept.capitalize()]}") + return '\n'.join(concept_prompt) + + +def find_operators(operators, operators_name): + opeartor_prompt = [] + for index, operator in enumerate(operators_name): + if operator in operators.keys(): + opeartor_prompt.append(f"{index + 1}. {operator.capitalize()}: {operators[operator.capitalize()]}") + return '\n'.join(opeartor_prompt) + + +if __name__ == '__main__': + client = OpenAI(api_key="xxx", base_url="https://ark.cn-beijing.volces.com/api/v3") + file = open( + r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output' + r'\merge_assertions\conic10k_output_1_new.json', + 'r', encoding='utf-8') + datas = json.load(file) + + operator_file = open(r'../ad_hoc_(can_ignore)/operators.json', 'r', encoding='utf-8') + all_operators = json.load(operator_file) + + concept_file = open(r'../ad_hoc_(can_ignore)/concepts.json', 'r', encoding='utf-8') + all_concepts = json.load(concept_file) + + new_file = open( + r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output\problems', + 'a', encoding='utf-8') + + res = [] + pattern = r'([A-Za-z_]\w*)\(' + for i, data in enumerate(datas): + dec = data["declarations"] + facts = data["facts"] + final_facts = [] + for fact in facts: + if "?" in fact: + query = fact + else: + final_facts.append(fact) + declarations = [] + concepts_name = [] + for key, value in dec.items(): + if value == "Expression": + continue + declarations.append(f"{key}: {value}") + concepts_name.append(value) + function_names = re.findall(pattern, '; '.join(facts)) + concepts_knowledge = find_concepts(all_concepts, list(set(concepts_name))) + operators_knowledge = find_operators(all_operators, list(set(function_names))) + assertion_knowledge = instruction.format(concepts_knowledge, operators_knowledge) + prompts = input_prompt.format('; '.join(declarations), '; '.join(final_facts), query) + # print(assertion_knowledge + '\n\n' + prompts) + # prompt = assertion_knowledge + '\n\n' + prompts + + completion = client.chat.completions.create( + model="deepseek-v3-241226", + messages=[ + {"role": "system", "content": assertion_knowledge}, + {"role": "user", "content": prompts}, + ], + ) + ans = completion.choices[0].message.content + data["math_problem"] = ans + + print(ans) + print('########################################################\n') + res.append(data) + + json.dump(res, new_file, indent=4, ensure_ascii=False) diff --git a/generate_dataset/generate_natural_language/_generate_nl_topv2.py b/generate_dataset/generate_natural_language/_generate_nl_topv2.py index ef38b56..27542fb 100644 --- a/generate_dataset/generate_natural_language/_generate_nl_topv2.py +++ b/generate_dataset/generate_natural_language/_generate_nl_topv2.py @@ -1,8 +1,8 @@ import warnings -from generate_dataset.build_labels.translate_format import _translate_format_topv2 -from generate_dataset.modeling.base_classes import FACT_T -from generate_dataset.gen_utils.access_llm import query_gpt +from build_labels.translate_format import _translate_format_topv2 +from modeling.base_classes import FACT_T +from gen_utils.access_llm import query_gpt # Instructions template for natural language generation generate_nl_instruct = '''You are a learned linguist, now please give some natural phrases to represent the meaning of given logical expression. @@ -110,7 +110,6 @@ def __check_original_words(sentence: str, words: list[str]) -> bool: def generate_nl_topv2(label: FACT_T) -> dict[str, FACT_T | list[str]]: # 将assertion的结构转为tuple[str, str],即assertion对应的文本描述 + assertion中涉及的operator等的desc # todo: 这个函数似乎可以作为default,不需要叫topv2 - label_str = _translate_format_topv2([label])[0] # hack: 先这样丑一点了,可以调整为自动的判断。也不应当访问protected member prompt = _gen_nl_prompt((label_str, label.description)) response = query_gpt(prompt) @@ -128,5 +127,4 @@ def generate_nl_topv2(label: FACT_T) -> dict[str, FACT_T | list[str]]: response = query_gpt(prompt) result = __clean_and_parse_response(response) attempt += 1 - return {} # 若三次尝试都未满足条件,返回空字典 diff --git a/generate_dataset/generate_natural_language/generate_nl.py b/generate_dataset/generate_natural_language/generate_nl.py index bd12fb4..94aedd4 100644 --- a/generate_dataset/generate_natural_language/generate_nl.py +++ b/generate_dataset/generate_natural_language/generate_nl.py @@ -1,11 +1,22 @@ import random +from pathlib import Path +import json +import sys + +from generate_dataset.postprocess.conic10k_ad_hoc import Declaration_record + +# 获取父目录路径并添加到 sys.path +parent_dir = str(Path(__file__).resolve().parent.parent) # 你用这行帮助移除generate_dataset作为模块的一部分 +# 不过如果这样的话,感觉不如直接在main.py的位置就导致第一级的目录叭,而不是这里? fixme(zcl): 你确认一下?我改是可以的 +sys.path.append(parent_dir) + from concurrent.futures import ThreadPoolExecutor -from .dataset_class import CustomDataset -from generate_dataset.modeling.base_classes import FACT_TYPE -from generate_dataset.postprocess._align_lemma import align_sent_label_by_lemmatization # fixme: 这样调用有点奇怪 -from generate_dataset.postprocess._complete_noun_phrases import get_full_noun_label -from ._generate_nl_topv2 import generate_nl_topv2 # fixme: 现在已经没有单独的generate_nl_topv2被使用了,都是通用的方案 +from generate_natural_language.dataset_class import CustomDataset, Example +from modeling.base_classes import FACT_TYPE +from postprocess._align_lemma import align_sent_label_by_lemmatization # fixme: 这样调用有点奇怪 +from postprocess._complete_noun_phrases import get_full_noun_label +from generate_natural_language._generate_nl_topv2 import generate_nl_topv2 # fixme: 现在已经没有单独的generate_nl_topv2被使用了,都是通用的方案 generate_nl_func_dict = {'topv2': generate_nl_topv2} @@ -33,12 +44,26 @@ def generate_nl(labels: list[FACT_TYPE], dataset_name: str, workers: int = 200) if __name__ == '__main__': - from generate_dataset.parse_funcs.parse_derivation import parse_derivations - - derivation_text_example = \ - ('intent:get_sunrise ( [ location: intent:get_location ( [ location_user: null ] [ search_radius: null ] ' - '[ location_modifier: London ] ) ] [ date_time: Next*spaceFriday ] [ weather: Rainy ] )') - dataset_type = 'topv2' - al_exp = parse_derivations(derivation_text_example, dataset_type) - # gen_labels = translate_format([al_exp], dataset_name=dataset_type) # todo: 现在类型错了 - # print(generate_nl(gen_labels, dataset_name=dataset_type)[0]) + from parse_funcs.parse_derivation import parse_derivations + import json + file = open(r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output\conic10k_output_5.jsonl', 'r', encoding='utf-8') + new_file = open(r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\assertions_output\conic10k_output_5_new.json', 'a', encoding='utf-8') + dataset_type = 'conic10k' + res = [] + for i, line in enumerate(file): + data = json.loads(line) + if "}" not in data["assertion"]: + derivation_text_example = data["assertion"] + al_exp = parse_derivations(derivation_text_example, dataset_type) + al_declarations = Declaration_record.get(al_exp, None) + data["id"] = i + if al_declarations is None: + data["declarations"] = None + else: + data["declarations"] = '; '.join(al_declarations) + data["facts"] = str(al_exp) + json.dump(data, new_file, indent=4, ensure_ascii=False) + new_file.write(",\n") + new_file.flush() + print(i, ' ', al_declarations, al_exp) + diff --git a/generate_dataset/main.py b/generate_dataset/main.py index ff2ddaf..cd9ec62 100644 --- a/generate_dataset/main.py +++ b/generate_dataset/main.py @@ -1,5 +1,6 @@ import sys from pathlib import Path +import json # 获取父目录路径并添加到 sys.path parent_dir = str(Path(__file__).resolve().parent.parent) @@ -22,7 +23,7 @@ def generate_dataset(dataset_name: str, num: int = 2) -> CustomDataset: :param num: 我这边异步比较草率,实际生成的数量可能会略大于num """ # 生成完后的标签了 - derivation_texts: list[str] = asyncio.run(generate_expressions(n=num)) + derivation_texts: list[str] = asyncio.run(generate_expressions(n=num)) # 如果需要靠传参指明路径的话,可以往dataset_file传 return derivation_texts # 用断言的方式表达 @@ -40,14 +41,13 @@ def generate_dataset(dataset_name: str, num: int = 2) -> CustomDataset: if __name__ == '__main__': - dataset_name = 'topv2' - n = 200 + # dataset_name = r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\rules\topv2_weather.cfg' + dataset_name = r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\rules\conic10k.cfg' + n = 5000 for i in range(1): dataset_test = generate_dataset(dataset_name, n) print(dataset_test) - # with open(f"./other_data_gpt/exchange_top_output_{i}.jsonl", "w", encoding="utf-8") as f: - # for e in dataset_test: - # import json - # - # json.dump({"input": e.input, "output": e.output}, f) - # f.write("\n") + with open(f"D:\\桌面\\6023\\generate_dataset\\semantic_parsing-q_upload_change\\generate_dataset\\assertions_output\\conic10k_output_5.jsonl", "a", encoding="utf-8") as f: + for e in dataset_test: + json.dump({"assertion": e}, f) + f.write("\n") diff --git a/generate_dataset/modeling/__init__.py b/generate_dataset/modeling/__init__.py index d877faf..0fa7f8d 100644 --- a/generate_dataset/modeling/__init__.py +++ b/generate_dataset/modeling/__init__.py @@ -1,3 +1,4 @@ from .base_classes import BaseIndividual, BaseOperator, Term, Assertion, Formula, FACT_TYPE, FACT_T -from .co_namespace import Declared_Operators from .topv2 import * +from .conic10k import * +from .co_namespace import Declared_Operators # Declared_Operator必须得先被导入某个建模后,才可以使用 diff --git a/generate_dataset/modeling/base_classes.py b/generate_dataset/modeling/base_classes.py index bdf5119..400d373 100644 --- a/generate_dataset/modeling/base_classes.py +++ b/generate_dataset/modeling/base_classes.py @@ -2,7 +2,8 @@ from typing import TypeVar -from generate_dataset.modeling.co_namespace import Declared_Operators +from . import dummy_operator +from .co_namespace import Declared_Operators class DuplicateError(Exception): @@ -82,6 +83,7 @@ class Term(object): """ def __init__(self, operator: BaseOperator, variables: list[BaseIndividual | Term]): self.operator = operator + self.variables = variables assert len(variables) == len(operator.inputType), \ f"variables {variables} do not match inputType {operator.inputType} of operator {operator.name}" @@ -113,8 +115,14 @@ def __getitem__(self, item): return self.__dict__[item] def __str__(self): - variables_str = ", ".join(map(str, self.variables)) - return f"{self.operator.name}({variables_str})" + if self.variables: + variables_str = ", ".join(map(str, self.variables)) + if self.operator == dummy_operator: + return f"{variables_str}" + else: + return f"{self.operator.name}({variables_str})" + else: + return "None" # hack: 这里应该是一个代表空值的特殊标记 def __repr__(self): variables_str = ", ".join(map(str, self.variables)) diff --git a/generate_dataset/modeling/conic10k.py b/generate_dataset/modeling/conic10k.py new file mode 100644 index 0000000..4e51293 --- /dev/null +++ b/generate_dataset/modeling/conic10k.py @@ -0,0 +1,685 @@ +from .base_classes import BaseOperator + + +Coordinate = BaseOperator( + name="Coordinate", + input_type=["POINT"], + output_type=["NUMBER", "NUMBER"], # hack: 不合类型约束的output_type + description="Get the (x, y) coordinates of a point" +) + +XCoordinate = BaseOperator( + name="XCoordinate", + input_type=["POINT"], + output_type="NUMBER", + description="Get the x-coordinate of a point" +) + +YCoordinate = BaseOperator( + name="YCoordinate", + input_type=["POINT"], + output_type="NUMBER", + description="Get the y-coordinate of a point" +) + +LocusEquation = BaseOperator( + name="LocusEquation", + input_type=["POINT"], + output_type="EXPRESSION", + description="Get the equation of a point's locus" +) + +Locus = BaseOperator( + name="Locus", + input_type=["POINT"], + output_type="CURVE", + description="Get the curve type representing a point's locus" +) + +Quadrant = BaseOperator( + name="Quadrant", + input_type=["POINT"], + output_type="NUMBER", + description="Determine which quadrant a point is in" +) + +Focus = BaseOperator( + name="Focus", + input_type=["CONICSECTION"], + output_type=["POINT", "POINT"], # hack: 不合类型约束的output_type + description="Get the foci of a conic section" +) + +RightFocus = BaseOperator( + name="RightFocus", + input_type=["CONICSECTION"], + output_type="POINT", + description="Get the right focus of a conic section" +) + +LeftFocus = BaseOperator( + name="LeftFocus", + input_type=["CONICSECTION"], + output_type="POINT", + description="Get the left focus of a conic section" +) + +LowerFocus = BaseOperator( + name="LowerFocus", + input_type=["CONICSECTION"], + output_type="POINT", + description="Get the lower focus of a conic section" +) + +UpperFocus = BaseOperator( + name="UpperFocus", + input_type=["CONICSECTION"], + output_type="POINT", + description="Get the upper focus of a conic section" +) + +FocalLength = BaseOperator( + name="FocalLength", + input_type=["CONICSECTION"], + output_type="NUMBER", + description="Get the focal length of a conic section" +) + +HalfFocalLength = BaseOperator( + name="HalfFocalLength", + input_type=["CONICSECTION"], + output_type="NUMBER", + description="Get half of the focal length of a conic section" +) + +SymmetryAxis = BaseOperator( + name="SymmetryAxis", + input_type=["CONICSECTION"], + output_type="AXIS", + description="Get the symmetry axis of a conic section" +) + +Eccentricity = BaseOperator( + name="Eccentricity", + input_type=["CONICSECTION"], + output_type="NUMBER", + description="Get the eccentricity of a conic section" +) + +Vertex = BaseOperator( + name="Vertex", + input_type=["CONICSECTION"], + output_type=["POINT", "POINT"], # hack: 不合类型约束的output_type + description="Get the vertices of a conic section" +) + +UpperVertex = BaseOperator( + name="UpperVertex", + input_type=["CONICSECTION"], + output_type="POINT", + description="Get the upper vertex of a conic section" +) + +LowerVertex = BaseOperator( + name="LowerVertex", + input_type=["CONICSECTION"], + output_type="POINT", + description="Get the lower vertex of a conic section" +) + +LeftVertex = BaseOperator( + name="LeftVertex", + input_type=["CONICSECTION"], + output_type="POINT", + description="Get the left vertex of a conic section" +) + +RightVertex = BaseOperator( + name="RightVertex", + input_type=["CONICSECTION"], + output_type="POINT", + description="Get the right vertex of a conic section" +) + +Directrix = BaseOperator( + name="Directrix", + input_type=["CONICSECTION"], + output_type=["LINE", "LINE"], # hack: 不合类型约束的output_type + description="Get the directrices of a conic section" +) + +LeftDirectrix = BaseOperator( + name="LeftDirectrix", + input_type=["CONICSECTION"], + output_type="LINE", + description="Get the left directrix of a conic section" +) + +RightDirectrix = BaseOperator( + name="RightDirectrix", + input_type=["CONICSECTION"], + output_type="LINE", + description="Get the right directrix of a conic section" +) + +MajorAxis = BaseOperator( + name="MajorAxis", + input_type=["ELLIPSE"], + output_type="LINESEGMENT", + description="Get the major axis of an ellipse" +) + +MinorAxis = BaseOperator( + name="MinorAxis", + input_type=["ELLIPSE"], + output_type="LINESEGMENT", + description="Get the minor axis of an ellipse" +) + +RealAxis = BaseOperator( + name="RealAxis", + input_type=["ELLIPSE"], + output_type="LINESEGMENT", + description="Get the real axis of an ellipse" +) + +ImaginaryAxis = BaseOperator( + name="ImaginaryAxis", + input_type=["ELLIPSE"], + output_type="LINESEGMENT", + description="Get the imaginary axis of an ellipse" +) + +LeftPart = BaseOperator( + name="LeftPart", + input_type=["HYPERBOLA"], + output_type="CURVE", + description="Get the left part of a hyperbola" +) + +RightPart = BaseOperator( + name="RightPart", + input_type=["HYPERBOLA"], + output_type="CURVE", + description="Get the right part of a hyperbola" +) + +Asymptote = BaseOperator( + name="Asymptote", + input_type=["HYPERBOLA"], + output_type=["LINE", "LINE"], # hack: 不合类型约束的output_type + description="Get the asymptotes of a hyperbola" +) + +Diameter = BaseOperator( + name="Diameter", + input_type=["CIRCLE"], + output_type="NUMBER", + description="Get the diameter of a circle" +) + +Radius = BaseOperator( + name="Radius", + input_type=["CIRCLE"], + output_type="NUMBER", + description="Get the radius of a circle" +) + +Perimeter = BaseOperator( + name="Perimeter", + input_type=["CONICSECTION"], + output_type="NUMBER", + description="Get the perimeter of a conic section" +) + +Center = BaseOperator( + name="Center", + input_type=["CONICSECTION"], + output_type="POINT", + description="Get the center of a conic section" +) + +Expression = BaseOperator( + name="Expression", + input_type=["CURVE"], + output_type="EXPRESSION", + description="Get the expression of a curve" +) + +LineOf = BaseOperator( + name="LineOf", + input_type=["POINT", "POINT"], + output_type="LINE", + description="Get the line passing through two points" +) + +Slope = BaseOperator( + name="Slope", + input_type=["LINE"], + output_type="NUMBER", + description="Get the slope of a line" +) + +Inclination = BaseOperator( + name="Inclination", + input_type=["LINE"], + output_type="NUMBER", + description="Get the inclination angle of a line" +) + +Intercept = BaseOperator( + name="Intercept", + input_type=["LINE", "AXIS"], + output_type="NUMBER", + description="Get the intercept of a line on an axis" +) + +LineSegmentOf = BaseOperator( + name="LineSegmentOf", + input_type=["POINT", "POINT"], + output_type="LINESEGMENT", + description="Get the line segment between two points" +) + +Length = BaseOperator( + name="Length", + input_type=["LINESEGMENT"], + output_type="NUMBER", + description="Get the length of a line segment" +) + +MidPoint = BaseOperator( + name="MidPoint", + input_type=["LINESEGMENT"], + output_type="POINT", + description="Get the midpoint of a line segment" +) + +OverlappingLine = BaseOperator( + name="OverlappingLine", + input_type=["LINESEGMENT"], + output_type="LINE", + description="Get the line that overlaps with a line segment" +) + +PerpendicularBisector = BaseOperator( + name="PerpendicularBisector", + input_type=["LINESEGMENT"], + output_type="LINE", + description="Get the perpendicular bisector of a line segment" +) + +Endpoint = BaseOperator( + name="Endpoint", + input_type=["LINESEGMENT"], + output_type=["POINT", "POINT"], # hack: 不合类型约束的output_type + description="Get the endpoints of a line segment" +) + +Projection = BaseOperator( + name="Projection", + input_type=["POINT", "LINE"], + output_type="POINT", + description="Get the projection of a point onto a line" +) + +InterceptChord = BaseOperator( + name="InterceptChord", + input_type=["LINE", "CONICSECTION"], + output_type="LINESEGMENT", + description="Get the chord intercepted by a line on a conic section" +) + +TriangleOf = BaseOperator( + name="TriangleOf", + input_type=["POINT", "POINT", "POINT"], + output_type="TRIANGLE", + description="Get the triangle formed by three points" +) + +InscribedCircle = BaseOperator( + name="InscribedCircle", + input_type=["TRIANGLE"], + output_type="CIRCLE", + description="Get the inscribed circle of a triangle" +) + +CircumCircle = BaseOperator( + name="CircumCircle", + input_type=["TRIANGLE"], + output_type="CIRCLE", + description="Get the circumcircle of a triangle" +) + +Incenter = BaseOperator( + name="Incenter", + input_type=["TRIANGLE"], + output_type="POINT", + description="Get the incenter of a triangle" +) + +Orthocenter = BaseOperator( + name="Orthocenter", + input_type=["TRIANGLE"], + output_type="POINT", + description="Get the orthocenter of a triangle" +) + +Circumcenter = BaseOperator( + name="Circumcenter", + input_type=["TRIANGLE"], + output_type="POINT", + description="Get the circumcenter of a triangle" +) + +AngleOf = BaseOperator( + name="AngleOf", + input_type=["POINT", "POINT", "POINT"], + output_type="DEGREE", + description="Get the angle formed by three points" +) + +VectorOf = BaseOperator( + name="VectorOf", + input_type=["POINT", "POINT"], + output_type="VECTOR", + description="Get the vector from one point to another" +) + +DotProduct = BaseOperator( + name="DotProduct", + input_type=["VECTOR", "VECTOR"], + output_type="NUMBER", + description="Calculate the dot product of two vectors" +) + +NumIntersection = BaseOperator( + name="NumIntersection", + input_type=["CURVE", "CURVE"], + output_type="NUMBER", + description="Get the number of intersection points between two curves" +) + +Intersection = BaseOperator( + name="Intersection", + input_type=["CURVE", "CURVE"], + output_type=["POINT", "POINT"], # hack: 不合类型约束的output_type + description="Get the intersection points of two curves" +) + +FootPoint = BaseOperator( + name="FootPoint", + input_type=["LINE", "LINE"], + output_type="POINT", + description="Get the foot point from one line to another" +) + +Distance = BaseOperator( + name="Distance", + input_type=["POINT", "POINT"], + output_type="NUMBER", + description="Calculate the distance between two points" +) + +Area = BaseOperator( + name="Area", + input_type=["CONICSECTION"], + output_type="NUMBER", + description="Calculate the area of a conic section" +) + +TangentPoint = BaseOperator( + name="TangentPoint", + input_type=["LINE", "CIRCLE"], + output_type="POINT", + description="Get the tangent point between a line and a circle" +) + +TangentOfPoint = BaseOperator( + name="TangentOfPoint", + input_type=["POINT", "CURVE"], + output_type="LINE", + description="Get the tangent line at a point on a curve" +) + +TangentOnPoint = BaseOperator( + name="TangentOnPoint", + input_type=["POINT", "CURVE"], + output_type="LINE", + description="Get the tangent line on a point of a curve" +) + +Abs = BaseOperator( + name="Abs", + input_type=["LINESEGMENT"], + output_type="NUMBER", + description="Get the absolute value (length) of a line segment" +) + +lg = BaseOperator( + name="lg", + input_type=["NUMBER"], + output_type="NUMBER", + description="Calculate the logarithm of a number" +) + +InterReciprocal = BaseOperator( + name="InterReciprocal", + input_type=["NUMBER"], + output_type="NUMBER", + description="Calculate the reciprocal of a number" +) + +sqrt = BaseOperator( + name="sqrt", + input_type=["NUMBER"], + output_type="NUMBER", + description="Calculate the square root of a number" +) + +Max = BaseOperator( + name="Max", + input_type=["NUMBER"], + output_type="NUMBER", + description="Get the maximum value" +) + +Min = BaseOperator( + name="Min", + input_type=["NUMBER"], + output_type="NUMBER", + description="Get the minimum value" +) + +ApplyUnit = BaseOperator( + name="ApplyUnit", + input_type=["NUMBER", "DEGREESTR"], + output_type=None, # hack: 不合类型约束的output_type + description="Apply a unit to a number" +) + +Between = BaseOperator( + name="Between", + input_type=["POINT", "POINT", "POINT"], + output_type="BOOL", + description="Check if a point is between two other points" +) + +IsIntersect = BaseOperator( + name="IsIntersect", + input_type=["CURVE", "CURVE"], + output_type="BOOL", + description="Check if two curves intersect" +) + +IsPerpendicular = BaseOperator( + name="IsPerpendicular", + input_type=["LINE", "LINE"], + output_type="BOOL", + description="Check if two lines are perpendicular" +) + +IsParallel = BaseOperator( + name="IsParallel", + input_type=["LINE", "LINE"], + output_type="BOOL", + description="Check if two lines are parallel" +) + +IsDiameter = BaseOperator( + name="IsDiameter", + input_type=["LINESEGMENT", "CIRCLE"], + output_type="BOOL", + description="Check if a line segment is a diameter of a circle" +) + +IsChordOf = BaseOperator( + name="IsChordOf", + input_type=["LINESEGMENT", "CONICSECTION"], + output_type="BOOL", + description="Check if a line segment is a chord of a conic section" +) + +IsTangent = BaseOperator( + name="IsTangent", + input_type=["LINE", "CONICSECTION"], + output_type="BOOL", + description="Check if a line is tangent to a conic section" +) + +IsInscribedCircle = BaseOperator( + name="IsInscribedCircle", + input_type=["CIRCLE", "TRIANGLE"], + output_type="BOOL", + description="Check if a circle is the inscribed circle of a triangle" +) + +IsCircumCircle = BaseOperator( + name="IsCircumCircle", + input_type=["CIRCLE", "TRIANGLE"], + output_type="BOOL", + description="Check if a circle is the circumcircle of a triangle" +) + +IsInTangent = BaseOperator( + name="IsInTangent", + input_type=["CIRCLE", "CIRCLE"], + output_type="BOOL", + description="Check if two circles are internally tangent" +) + +IsOutTangent = BaseOperator( + name="IsOutTangent", + input_type=["CIRCLE", "CIRCLE"], + output_type="BOOL", + description="Check if two circles are externally tangent" +) + +PointOnCurve = BaseOperator( + name="PointOnCurve", + input_type=["POINT", "CURVE"], + output_type="BOOL", + description="Check if a point lies on a curve" +) + +And = BaseOperator( + name="And", + input_type=["ASSERTION", "ASSERTION"], + output_type="BOOL", + description="Logical AND operation between two assertions" +) + +Negation = BaseOperator( + name="Negation", + input_type=["ASSERTION"], + output_type="BOOL", + description="Logical negation of an assertion" +) + +all_operators_conic10k = { + "Coordinate": Coordinate, + "XCoordinate": XCoordinate, + "YCoordinate": YCoordinate, + "LocusEquation": LocusEquation, + "Locus": Locus, + "Quadrant": Quadrant, + "Focus": Focus, + "RightFocus": RightFocus, + "LeftFocus": LeftFocus, + "LowerFocus": LowerFocus, + "UpperFocus": UpperFocus, + "FocalLength": FocalLength, + "HalfFocalLength": HalfFocalLength, + "SymmetryAxis": SymmetryAxis, + "Eccentricity": Eccentricity, + "Vertex": Vertex, + "UpperVertex": UpperVertex, + "LowerVertex": LowerVertex, + "LeftVertex": LeftVertex, + "RightVertex": RightVertex, + "Directrix": Directrix, + "LeftDirectrix": LeftDirectrix, + "RightDirectrix": RightDirectrix, + "MajorAxis": MajorAxis, + "MinorAxis": MinorAxis, + "RealAxis": RealAxis, + "ImaginaryAxis": ImaginaryAxis, + "LeftPart": LeftPart, + "RightPart": RightPart, + "Asymptote": Asymptote, + "Diameter": Diameter, + "Radius": Radius, + "Perimeter": Perimeter, + "Center": Center, + "Expression": Expression, + "LineOf": LineOf, + "Slope": Slope, + "Inclination": Inclination, + "Intercept": Intercept, + "LineSegmentOf": LineSegmentOf, + "Length": Length, + "MidPoint": MidPoint, + "OverlappingLine": OverlappingLine, + "PerpendicularBisector": PerpendicularBisector, + "Endpoint": Endpoint, + "Projection": Projection, + "InterceptChord": InterceptChord, + "TriangleOf": TriangleOf, + "InscribedCircle": IsInscribedCircle, + "CircumCircle": CircumCircle, + "Incenter": Incenter, + "Orthocenter": Orthocenter, + "Circumcenter": Circumcenter, + "AngleOf": AngleOf, + "VectorOf": VectorOf, + "DotProduct": DotProduct, + "NumIntersection": NumIntersection, + "Intersection": Intersection, + "FootPoint": FootPoint, + "Distance": Distance, + "Area": Area, + "TangentPoint": TangentPoint, + "TangentOfPoint": TangentOfPoint, + "TangentOnPoint": TangentOnPoint, + "Abs": Abs, + "lg": lg, + "InterReciprocal": InterReciprocal, + "sqrt": sqrt, + "Max": Max, + "Min": Min, + "ApplyUnit": ApplyUnit, + "Between": Between, + "IsIntersect": IsIntersect, + "IsPerpendicular": IsPerpendicular, + "IsParallel": IsParallel, + "IsDiameter": IsDiameter, + "IsChordOf": IsChordOf, + "IsTangent": IsTangent, + "IsInscribedCircle": IsInscribedCircle, + "IsCircumCircle": IsCircumCircle, + "IsInTangent": IsInTangent, + "IsOutTangent": IsOutTangent, + "PointOnCurve": PointOnCurve, + "And": And, + "Negation": Negation, +} diff --git a/generate_dataset/modeling/topv2.py b/generate_dataset/modeling/topv2.py index 19e606d..003aa3e 100644 --- a/generate_dataset/modeling/topv2.py +++ b/generate_dataset/modeling/topv2.py @@ -128,66 +128,85 @@ # get_event = BaseOperator( name="GET_EVENT", - input_type=["CATEGORY_EVENT", "DATE_TIME", "LOCATION", "ATTRIBUTE_EVENT", "NAME_EVENT", "ORDINAL", "ORGANIZER_EVENT"], + input_type=["CATEGORY_EVENT", "DATE_TIME", "LOCATION", + "ATTRIBUTE_EVENT", "NAME_EVENT", "ORDINAL", "ORGANIZER_EVENT"], output_type="event or activity information", - description="get event or activity information\t[SL:CATEGORY_EVENT: event category\t[SL:DATE_TIME: event occurrence time\t[SL:LOCATION: event occurrence location" - "\t[SL:ATTRIBUTE_EVENT: some attribute with the event\t[SL:NAME_EVENT: event name\t[SL:ORDINAL: the ordinal number of the selected reminder or pointing towards the future" + description="get event or activity information\t[SL:CATEGORY_EVENT: event category\t[SL:DATE_TIME: event " + "occurrence time\t[SL:LOCATION: event occurrence location" + "\t[SL:ATTRIBUTE_EVENT: some attribute with the event\t[SL:NAME_EVENT: event name\t[SL:ORDINAL: the " + "ordinal number of the selected reminder or pointing towards the future" ) create_reminder = BaseOperator( name="CREATE_REMINDER", input_type=["PERSON_REMINDED", "REMINDER_DATE_TIME", "TODO", "RECURRING_DATE_TIME"], output_type="create reminder", - description="create reminder.\t[SL:PERSON_REMINDED: the reminded target\t[SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder of things to do\t[SL:ORDINAL: reminder of things to do\t[SL:RECURRING_DATE_TIME: number and duration of recurring" + description="create reminder.\t[SL:PERSON_REMINDED: the reminded target\t[SL:REMINDER_DATE_TIME: reminder date " + "time\t[SL:TODO: reminder of things to do\t[SL:ORDINAL: reminder of things to do\t[" + "SL:RECURRING_DATE_TIME: number and duration of recurring" ) delete_reminder = BaseOperator( name="DELETE_REMINDER", input_type=["PERSON_REMINDED", "REMINDER_DATE_TIME", "TODO", "AMOUNT", "ORDINAL", "RECURRING_DATE_TIME"], output_type="delete reminder", - description="delete previously set reminders.\t[SL:PERSON_REMINDED: the reminded target\t[SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder of things to do\t[SL:AMOUNT: number of selected or pointed reminders\t[SL:ORDINAL: the ordinal number of the selected reminder\t[SL:RECURRING_DATE_TIME: number and duration of recurring" + description="delete previously set reminders.\t[SL:PERSON_REMINDED: the reminded target\t[SL:REMINDER_DATE_TIME: " + "reminder date time\t[SL:TODO: reminder of things to do\t[SL:AMOUNT: number of selected or pointed " + "reminders\t[SL:ORDINAL: the ordinal number of the selected reminder\t[SL:RECURRING_DATE_TIME: number " + "and duration of recurring" ) get_reminder = BaseOperator( name="GET_REMINDER", input_type=["PERSON_REMINDED", "REMINDER_DATE_TIME", "TODO", "AMOUNT", "ORDINAL", "METHOD_RETRIEVAL_REMINDER"], output_type="get reminder information", - description="get previously set reminder content.\t[SL:PERSON_REMINDED: the reminded target\t[SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder of things to do\t[SL:AMOUNT: number of selected or pointed reminders\t[SL:ORDINAL: the ordinal number of the selected reminder\t[SL:METHOD_RETRIEVAL_REMINDER: Reminder method" + description="get previously set reminder content.\t[SL:PERSON_REMINDED: the reminded target\t[" + "SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder of things to do\t[SL:AMOUNT: number of " + "selected or pointed reminders\t[SL:ORDINAL: the ordinal number of the selected reminder\t[" + "SL:METHOD_RETRIEVAL_REMINDER: Reminder method" ) get_reminder_amount = BaseOperator( name="GET_REMINDER_AMOUNT", input_type=["PERSON_REMINDED", "REMINDER_DATE_TIME", "TODO"], output_type="get reminder amount", - description="get number of times the reminder has been set\t[SL:PERSON_REMINDED: the reminded target\t[SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder of things to do" + description="get number of times the reminder has been set\t[SL:PERSON_REMINDED: the reminded target\t[" + "SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder of things to do" ) get_reminder_date_time = BaseOperator( name="GET_REMINDER_DATE_TIME", input_type=["PERSON_REMINDED", "DATE_TIME", "TODO", "AMOUNT", "ORDINAL"], output_type="get reminder date time", - description="get the reminder time for the previously set reminder\t[SL:PERSON_REMINDED: the reminded target\t[SL:DATE_TIME: current date time\t[SL:TODO: reminder of things to do\t[SL:AMOUNT: number of selected or pointed reminders\t[SL:ORDINAL: the ordinal number of the selected reminder" + description="get the reminder time for the previously set reminder\t[SL:PERSON_REMINDED: the reminded target\t[" + "SL:DATE_TIME: current date time\t[SL:TODO: reminder of things to do\t[SL:AMOUNT: number of selected " + "or pointed reminders\t[SL:ORDINAL: the ordinal number of the selected reminder" ) get_reminder_location = BaseOperator( name="GET_REMINDER_LOCATION", input_type=["PERSON_REMINDED", "REMINDER_DATE_TIME", "TODO", "ORDINAL", "METHOD_RETRIEVAL_REMINDER"], output_type="get reminder location", - description="get the event sending location of the previously set reminder\t[SL:PERSON_REMINDED: the reminded target\t[SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder of things to do\t[SL:ORDINAL: the ordinal number of the selected reminder\t[SL:METHOD_RETRIEVAL_REMINDER: Reminder method" + description="get the event sending location of the previously set reminder\t[SL:PERSON_REMINDED: the reminded " + "target\t[SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder of things to do\t[SL:ORDINAL: " + "the ordinal number of the selected reminder\t[SL:METHOD_RETRIEVAL_REMINDER: Reminder method" ) update_reminder_todo = BaseOperator( name="UPDATE_REMINDER_TODO", input_type=["PERSON_REMINDED", "REMINDER_DATE_TIME", "TODO", "TODO_NEW", "RECURRING_DATE_TIME"], output_type="update reminder todo", - description="Update the reminder memory from Todo to the new Todo\t[SL:PERSON_REMINDED: the reminded target\t[SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder content set in the past\t[SL:TODO_NEW: Updated reminder content\t[SL:RECURRING_DATE_TIME: number and duration of recurring" + description="Update the reminder memory from Todo to the new Todo\t[SL:PERSON_REMINDED: the reminded target\t[" + "SL:REMINDER_DATE_TIME: reminder date time\t[SL:TODO: reminder content set in the past\t[SL:TODO_NEW: " + "Updated reminder content\t[SL:RECURRING_DATE_TIME: number and duration of recurring" ) get_todo = BaseOperator( name="GET_TODO", input_type=["TODO_ANOTHER", "TODO_DATE_TIME", "ATTENDEE"], output_type="get todo information", - description="get todo information\t[SL:TODO_ANOTHER: reminder of things to do\t[SL:TODO_DATE_TIME:todo occurrence time\t[SL:ATTENDEE:todo occurrence time\t[SL:ATTENDEE:attendee" + description="get todo information\t[SL:TODO_ANOTHER: reminder of things to do\t[SL:TODO_DATE_TIME:todo occurrence " + "time\t[SL:ATTENDEE:todo occurrence time\t[SL:ATTENDEE:attendee" ) get_contact = BaseOperator( @@ -201,7 +220,7 @@ name="GET_RECURRING_DATE_TIME", input_type=["FREQUENCY", "DATE_TIME"], output_type="number and duration of recurring", - description = "number and duration of recurring\t[SL:FREQUENCY: cycle frequency\t[SL:DATE_TIME: cycle time period" + description="number and duration of recurring\t[SL:FREQUENCY: cycle frequency\t[SL:DATE_TIME: cycle time period" ) dummy_operator = BaseOperator( @@ -211,8 +230,7 @@ description='' ) - -all_operators = { +all_operators_topv2 = { "GET_WEATHER": get_weather, "GET_SUNSET": get_sunset, "GET_SUNRISE": get_sunrise, diff --git a/generate_dataset/parse_funcs/_parse_derivation_conic10k.py b/generate_dataset/parse_funcs/_parse_derivation_conic10k.py new file mode 100644 index 0000000..03a787b --- /dev/null +++ b/generate_dataset/parse_funcs/_parse_derivation_conic10k.py @@ -0,0 +1,171 @@ +from generate_dataset.modeling import Assertion, BaseOperator, Term, BaseIndividual, Declared_Operators, dummy_operator +from generate_dataset.postprocess.conic10k_ad_hoc import Declaration_record + + +def __split_operator_variables(derivation_text: str) -> tuple[str, str]: + """ + Splits the derivation text into the operator name and the variables text. + Example: "get_sunset([LOCATION:null][DATE_TIME:get_next_day(...)][weather:Rainy])" + returns ("get_sunset", "[LOCATION:null][DATE_TIME:get_next_day(...)][weather:Rainy]") + """ + + # TODO + # 对于'InterReciprocal(Eccentricity(CONICSECTION:s)),NumIntersection(LeftPart(HYPERBOLA:d),CURVE:n)'这样的另写,相当于一个算子里的2个输入都是嵌套 + # 目前合成的数据都是直接把这样的丢掉 + + start = derivation_text.find("(") + end = derivation_text.rfind(")") + if start == -1 or end == -1: + raise ValueError("Invalid derivation text format") + operator_name = derivation_text[:start].strip() + variables_text = derivation_text[start + 1:end].strip() + return operator_name, variables_text + + +def __extract_variables_al(variables_text: str, operator: BaseOperator) \ + -> tuple[list[BaseIndividual | Term], list[str]]: + """ + Extracts variables from the variables text and returns them as a list of BaseIndividual or Term objects. + Example: "(LOCATION:null, DATE_TIME:get_next_day(...))" + returns [BaseIndividual("LOCATION", null), Term(get_next_day, [...])] + """ + variables = [] + declarations = [] + inner_variable_texts = variables_text.split(',') + merged_inner_variable_texts = __merge_variables(inner_variable_texts) + for inner_variable_text in merged_inner_variable_texts: + inner_variable_text = inner_variable_text.strip() + if "(" in inner_variable_text: # 说明有嵌套 + sub_operator_name, sub_variables_text = __split_operator_variables(inner_variable_text) + sub_operator = Declared_Operators[sub_operator_name] + sub_variables, sub_declarations = __extract_variables_al(sub_variables_text, sub_operator) + variables.append(Term(operator=sub_operator, variables=sub_variables)) + declarations.extend(sub_declarations) + + else: + inner_texts = inner_variable_text.split(",") + for text in inner_texts: + name = text.split(":")[0] + value = text.split(":")[-1] + + assert name in operator.inputType + [operator.outputType], \ + f"Name {name} not found in input types {operator.inputType} or output type {operator.outputType}" + + variables.append(BaseIndividual(value=value)) + declarations.append(f"{value}: {name}") + + return variables, declarations + + +def __merge_variables(variables_list: list[str]) -> list[str]: + merged_list = [] + temp_buffer = [] + open_count = 0 # 跟踪未闭合的括号数量 + + for item in variables_list: + # 计算当前项的括号数量 + open_count += item.count('(') - item.count(')') + + # 添加到缓冲区 + temp_buffer.append(item) + + # 如果所有括号都已闭合 + if open_count == 0: + # 合并缓冲区内容 + merged_item = ''.join([s if i == 0 else f', {s}' + for i, s in enumerate(temp_buffer)]) + merged_list.append(merged_item) + temp_buffer = [] + + # 处理最后可能未闭合的括号 + if temp_buffer: + merged_list.append(''.join(temp_buffer)) + + return merged_list + + +def _parse_derivation_conic10k(derivation_text: str) -> Assertion | None: + """ + 把生成的表达式转为assertion logic的格式 + Operator(variable) = concept_individual + """ + derivation_text = derivation_text.replace(' ', '') + count = derivation_text.count("equals") + if count >= 2: + # TODO + # 这是为了识别 Negation(Term = Term) = BOOL 这样的表达式,可以直接丢掉 + + # left_part, sep, right_part = derivation_text.rpartition("equals") + # left_assertion, left_declarations = _parse_derivation_conic10k(left_part) + # term_lhs = Term(operator=dummy_operator, + # variables=left_assertion) + + # if "(" in right_part: # 右式也是一个Operator(variable)的形式 + # right_operator_name, right_variable_text = __split_operator_variables(right_part) + # right_operator = Declared_Operators[right_operator_name] + # right_variables, right_declarations = __extract_variables_al(right_variable_text, right_operator) + # term_rhs = Term(operator=right_operator, + # variables=right_variables + # ) + # else: # 右式直接是Concept: variable的形式 + # right_variables = right_part.split(":")[-1] + # right_concepts = right_part.split(":")[0] + # right_declarations = [f"{right_variables}: {right_concepts}"] + # term_rhs = Term(operator=dummy_operator, + # variables=right_variables) + # return Assertion(lhs=term_lhs, rhs=term_rhs), left_declarations + right_declarations + return None + + elif count == 0: # fixme: 为什么会有无equals的情况 + operator_name, variable_text = __split_operator_variables(derivation_text) + operator = Declared_Operators[operator_name] + variables, declarations = __extract_variables_al(variable_text, operator) + term_lhs = Term(operator=operator, + variables=variables) + term_rhs = Term(operator=dummy_operator, + variables=[]) + + fact = Assertion(lhs=term_lhs, rhs=term_rhs) + Declaration_record[fact] = declarations + return fact + + else: + left_part = derivation_text.split("equals")[0] + right_part = derivation_text.split("equals")[-1] + left_operator_name, left_variable_text = __split_operator_variables(left_part) + left_operator = Declared_Operators[left_operator_name] + left_variables, left_declarations = __extract_variables_al(left_variable_text, left_operator) + term_lhs = Term(operator=left_operator, + variables=left_variables) + + if "(" in right_part and "EXPRESSION" not in right_part: # 右式也是一个Operator(variable)的形式 + right_operator_name, right_variable_text = __split_operator_variables(right_part) + + # TODO + # 需要解决Point(p) = (Number, Number)的特殊右式表达式,目前直接忽略 + if right_operator_name == '': + return None + + right_operator = Declared_Operators[right_operator_name] + right_variables, right_declarations = __extract_variables_al(right_variable_text, right_operator) + term_rhs = Term(operator=right_operator, + variables=right_variables + ) + else: # 右式直接是Concept: variable的形式 + right_variables = [BaseIndividual(right_part.split(":")[-1])] + right_concepts = right_part.split(":")[0] + right_declarations = [f"{right_variables}: {right_concepts}"] + term_rhs = Term(operator=dummy_operator, + variables=right_variables) + + fact = Assertion(lhs=term_lhs, rhs=term_rhs) + Declaration_record[fact] = left_declarations + right_declarations + return fact + + +if __name__ == '__main__': + derivation_text_example = \ + ("Coordinate ( LeftFocus ( CONICSECTION: T ) ) equals ( sqrt ( Quadrant ( POINT: t ) ), DotProduct ( VECTOR: " + "k, VECTOR: D ) )") + assertions = _parse_derivation_conic10k(derivation_text_example) + print(f"{'; '.join(Declaration_record[assertions])}\n{assertions}") diff --git a/generate_dataset/parse_funcs/_parse_derivation_topv2.py b/generate_dataset/parse_funcs/_parse_derivation_topv2.py index 4435a5b..3571cd6 100644 --- a/generate_dataset/parse_funcs/_parse_derivation_topv2.py +++ b/generate_dataset/parse_funcs/_parse_derivation_topv2.py @@ -1,6 +1,4 @@ -from generate_dataset.modeling.base_classes import Assertion, BaseOperator, Term, BaseIndividual -# Declared_Operator必须得先被导入某个建模后,才可以使用 -from generate_dataset.modeling.co_namespace import Declared_Operators +from generate_dataset.modeling import Assertion, BaseOperator, Term, BaseIndividual, Declared_Operators def __clean_text(text: str) -> str: @@ -33,6 +31,7 @@ def __extract_variables(variables_text: str, operator: BaseOperator) -> list[Bas Example: "[LOCATION:null][DATE_TIME:get_next_day(...)][weather:Rainy]" returns [BaseIndividual("LOCATION", null), Term(get_next_day, [...]), BaseIndividual("WEATHER", "Rainy")] """ + def find_matching_bracket(text: str, start: int) -> int: """ Finds the index of the matching closing bracket for a nested structure. @@ -51,12 +50,12 @@ def find_matching_bracket(text: str, start: int) -> int: raise ValueError("Mismatched brackets in variables text") variables = [] - i = 0 - while i < len(variables_text): - if variables_text[i] == '[': + p = 0 + while p < len(variables_text): + if variables_text[p] == '[': # Find the closing bracket for this variable - end = find_matching_bracket(variables_text, i) - inner_text = variables_text[i + 1:end] # Strip the outer brackets + end = find_matching_bracket(variables_text, p) + inner_text = variables_text[p + 1:end] # Strip the outer brackets name, value = inner_text.split(":", 1) assert name in operator.inputType + [operator.outputType], \ @@ -71,9 +70,9 @@ def find_matching_bracket(text: str, start: int) -> int: value = __clean_text(value) variables.append(BaseIndividual(value=value)) - i = end + 1 + p = end + 1 else: - i += 1 + p += 1 return variables @@ -97,5 +96,6 @@ def _parse_derivation_topv2(derivation_text: str) -> Assertion: if __name__ == '__main__': derivation_text_example = \ - 'intent:GET_EVENT ( [ CATEGORY_EVENT: null ] [ DATE_TIME: later*spacetoday ] [ LOCATION: null ] [ ATTRIBUTE_EVENT: families ] [ NAME_EVENT: null ] [ ORDINAL: null ] [ ORGANIZER_EVENT: null ] )' + ('intent:GET_EVENT ( [ CATEGORY_EVENT: null ] [ DATE_TIME: later*spacetoday ] [ LOCATION: null ] [ ' + 'ATTRIBUTE_EVENT: families ] [ NAME_EVENT: null ] [ ORDINAL: null ] [ ORGANIZER_EVENT: null ] )') print(_parse_derivation_topv2(derivation_text_example)) diff --git a/generate_dataset/parse_funcs/parse_derivation.py b/generate_dataset/parse_funcs/parse_derivation.py index 8155851..271c7e6 100644 --- a/generate_dataset/parse_funcs/parse_derivation.py +++ b/generate_dataset/parse_funcs/parse_derivation.py @@ -1,9 +1,10 @@ -from ._parse_derivation_topv2 import _parse_derivation_topv2 +from ._parse_derivation_topv2 import _parse_derivation_topv2, _parse_derivation_conic10k from generate_dataset.modeling.base_classes import Assertion, Formula _FACT_TYPE = Assertion | Formula -parse_funcs_dict = {'topv2': _parse_derivation_topv2} +parse_funcs_dict = {'topv2': _parse_derivation_topv2, + 'conic10k': _parse_derivation_conic10k} def parse_derivations(derivation_texts: list[str] | str, dataset_name: str) -> _FACT_TYPE | list[_FACT_TYPE]: @@ -11,7 +12,7 @@ def parse_derivations(derivation_texts: list[str] | str, dataset_name: str) -> _ if isinstance(derivation_texts, str): return parse_func(derivation_texts) - return [parse_func(d) for d in derivation_texts] + return [parse_func(d) for d in derivation_texts if d] # 可能有不合法的情况,从而为None if __name__ == '__main__': diff --git a/generate_dataset/postprocess/_align_lemma.py b/generate_dataset/postprocess/_align_lemma.py index 031d634..a0fa52e 100644 --- a/generate_dataset/postprocess/_align_lemma.py +++ b/generate_dataset/postprocess/_align_lemma.py @@ -1,6 +1,8 @@ # 考虑输入和label在lemmatization层面的对齐 -from generate_dataset.gen_utils.spacy_load import load_spacy_model -from generate_dataset.modeling import FACT_T, Assertion, Formula, Term, BaseIndividual +import sys +sys.path.append(r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset') +from gen_utils.spacy_load import load_spacy_model +from modeling import FACT_T, Assertion, Formula, Term, BaseIndividual nlp = load_spacy_model("en_core_web_sm") # fixme: 重复加载 diff --git a/generate_dataset/postprocess/_complete_noun_phrases.py b/generate_dataset/postprocess/_complete_noun_phrases.py index c067bdc..5c536df 100644 --- a/generate_dataset/postprocess/_complete_noun_phrases.py +++ b/generate_dataset/postprocess/_complete_noun_phrases.py @@ -1,13 +1,14 @@ import string - -from generate_dataset.gen_utils.spacy_load import load_spacy_model -from generate_dataset.modeling import FACT_T, BaseIndividual -from generate_dataset.postprocess._align_lemma import _extract_individuals +import sys +sys.path.append(r'D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset') +from gen_utils.spacy_load import load_spacy_model +from modeling import FACT_T, BaseIndividual +from postprocess._align_lemma import _extract_individuals nlp = load_spacy_model("en_core_web_sm") -stopwords = set(open(r"C:\Users\YueG_W\Documents\GitHub\semantic_parsing\generate_dataset\postprocess\stopwords.txt", "r", encoding="utf-8").read().splitlines()) -# hack: 不知道为什么相对路径不对,先用绝对的了 +stopwords = set(open(r"D:\桌面\6023\generate_dataset\semantic_parsing-q_upload_change\generate_dataset\postprocess\stopwords.txt", "r", encoding="utf-8").read().splitlines()) +# XXX: 不知道为什么相对路径不对,先用绝对的了 def _extract_noun_phrases(doc): diff --git a/generate_dataset/postprocess/conic10k_ad_hoc.py b/generate_dataset/postprocess/conic10k_ad_hoc.py new file mode 100644 index 0000000..22e0895 --- /dev/null +++ b/generate_dataset/postprocess/conic10k_ad_hoc.py @@ -0,0 +1,2 @@ +# 为了方便在代码过程中会有一些不合流程的代码,通过这个文件进行相关的处理 +Declaration_record = {} \ No newline at end of file diff --git a/generate_dataset/rules/conic10k.cfg b/generate_dataset/rules/conic10k.cfg index 2c6a793..3201adc 100644 --- a/generate_dataset/rules/conic10k.cfg +++ b/generate_dataset/rules/conic10k.cfg @@ -1,112 +1,181 @@ -# 在top数据集中,不存在TERM=TERM,只有TERM。当然严谨来说,这里应该称作一个formula / fact / proposition等 $START=$ASSERTION -# 这里收录所有的算子。每个FACT是由predicate (xx)组成的。但考虑到CFG的表达能力,我们这里需要罗列predicate+对应arity的组合 -# 而不是分别用PREDICATE和ARITY两个非终止节点代替 -$ASSERTION=Coordinate ( $POINT ) equals ( $NUMBER $NUMBER ) -|XCoordinate ( $POINT ) equals ( $NUMBER ) -|YCoordinate ( $POINT ) equals ( $NUMBER ) -|LocusEquation ( $POINT ) equals ( $EXPRESSION ) -|Locus ( $POINT ) equals ( $CURVE ) -|Quadrant ( $POINT ) equals ( $NUMBER ) -|Focus ( $CONICSECTION ) equals ( $POINTS ) -|RightFocus ( $CONICSECTION ) equals ( $POINT ) -|LeftFocus ( $CONICSECTION ) equals ( $POINT ) -|LowerFocus ( $CONICSECTION ) equals ( $POINT ) -|UpperFocus ( $CONICSECTION ) equals ( $POINT ) -|FocalLength ( $CONICSECTION ) equals ( $NUMBER ) -|HalfFocalLength ( $CONICSECTION ) equals ( $NUMBER ) -|SymmetryAxis ( $CONICSECTION ) equals ( $AXIS ) -|Eccentricity ( $CONICSECTION ) equals ( $NUMBER ) -|Vertex ( $CONICSECTION ) equals ( $POINTS ) -|UpperVertex ( $ELLIPSE_HYPERBOLA ) equals ( $POINT ) -|LowerVertex ( $ELLIPSE_HYPERBOLA ) equals ( $POINT ) -|LeftVertex ( $ELLIPSE_HYPERBOLA ) equals ( $POINT ) -|RightVertex ( $ELLIPSE_HYPERBOLA ) equals ( $POINT ) -|Directrix ( $CONICSECTION ) equals ( $LINES ) -|LeftDirectrix ( $CONICSECTION ) equals ( $LINE ) -|RightDirectrix ( $CONICSECTION ) equals ( $LINE ) -|MajorAxis ( $ELLIPSE ) equals ( $LINESEGMENT ) -|MinorAxis ( $ELLIPSE ) equals ( $LINESEGMENT ) -|RealAxis ( $ELLIPSE ) equals ( $LINESEGMENT ) -|ImageinaryAxis ( $ELLIPSE ) equals ( $LINESEGMENT ) -|LeftPart ( $HYPERBOLA ) equals ( $CURVE ) -|RightPart ( $HYPERBOLA ) equals ( $CURVE ) -|Asymptote ( $HYPERBOLA ) equals ( $TWOLINES ) -|Diameter ( $DIAMETER ) equals ( $NUMBER ) -|Radius ( $DIAMETER ) equals ( $NUMBER ) -|Perimeter ( $CIRCLE_ELLIPSE ) equals ( $NUMBER ) -|Center ( $CIRCLE_ELLIPSE ) equals ( $POINT ) -|Expression( $CURVE ) equals ( $EXPRESSION ) -|LineOf( $POINT $POINT ) equals ( $LINE ) -|Slope( $LINE ) equals ( $NUMBER ) -|Inclination( $LINE ) equals ( $NUMBER ) -|Intercept( $LINE $AXIS ) equals ( $NUMBER ) -|LineSegmentOf( $POINT $POINT ) equals ( $LINESEGMENT ) -|Length( $LINESEGMENT ) equals ( $NUMBER ) -|MidPoint( $LINESEGMENT ) equals ( $POINT ) -|OverlappingLine( $LINESEGMENT ) equals ( $LINE ) -|PerpendicularBisector( $LINESEGMENT ) equals ( $LINE ) -|Endpoint( $LINESEGMENT ) equals ( $TWOPOINTS ) -|Endpoint( $RAY ) equals ( $POINT ) -|Projection( $POINT $LINE ) equals ( $POINT ) -|Projection( $POINT $AXIS ) equals ( $POINT ) -|InterceptChord( $LINE $CONICSECTION ) equals ( $LINESEGMENT ) -|TriangleOf( $POINT $POINT $POINT ) equals ( $TRIANGLE ) -|InscribedCircle( $TRIANGLE ) equals ( $CIRCLE ) -|CircumCircle( $TRIANGLE ) equals ( $CIRCLE ) -|Incenter( $TRIANGLE ) equals ( $POINT ) -|Orthocenter( $TRIANGLE ) equals ( $POINT ) -|Circumcenter( $TRIANGLE ) equals ( $POINT ) -|AngleOf( $POINT $POINT $POINT ) equals ( $NUMBER ) -|VectorOf( $POINT $POINT ) equals ( $VECTOR ) -|DotProduct( $VECTOR $VECTOR ) equals ( $NUMBER ) -|NumIntersection( $AXIS_CURVE $AXIS_CURVE ) equals ( $NUMBER ) -|Intersection( $AXIS_CURVE $AXIS_CURVE ) equals ( $POINTS ) -|FootPoint( $LINE_LINESEGMENT $LINE_LINESEGMENT ) equals ( $POINT ) -|DISTANCE( $POINT_LINE $POINT_LINE ) equals ( $NUMBER ) -|Area( $CIRCLE ) equals ( $NUMBER ) -|Area( $ELLIPSE ) equals ( $NUMBER ) -|Area( $TRIANGLE ) equals ( $NUMBER ) -|TangentPoint( $LINE $CIRCLE ) equals ( $POINT ) -|TangentOfPoint( $POINT $CURVE ) equals ( $LINE ) -|TangentOnPoint( $POINT $CURVE ) equals ( $LINE ) -|Abs( $NUMBER ) equals ( $NUMBER ) -|Abs( $LINESEGMENT ) equals ( $NUMBER ) -|lg( $NUMBER ) equals ( $NUMBER ) -|InterReciprocal( $NUMBER ) equals ( $NUMBER ) -|sqrt( $NUMBER ) equals ( $NUMBER ) -|Max( $NUMBER ) equals ( $NUMBER ) -|Min( $NUMBER ) equals ( $NUMBER ) -|Range( $NUMBER ) equals ( $NUMBER $NUMBER ) -|WhenMin( $NUMBER ) -|WhenMax( $NUMBER ) -|ApplyUnit( $NUMBER $DEGREE ) -|ApplyUnit( $NUMBER $RAD ) -|In( $NUMBER ( $NUMBER $NUMBER ) ) -|Between( $POINT $POINT $POINT ) -|IsIntersect( $AXIS_CURVE $AXIS_CURVE ) -|IsPerpendicular( $LINE_LINESEGMENT_AXIS $LINE_LINESEGMENT_AXIS ) -|IsParallel( $LINE_LINESEGMENT_AXIS $LINE_LINESEGMENT_AXIS ) -|IsDiameter( $LINESEGMENT $CIRCLE ) -|IsChordOf( $LINESEGMENT $CONICSECTION ) -|IsTangent( $LINE $CONICSECTION ) -|IsInscribedCircle( $CIRCLE $TRIANGLE ) -|IsCircumCircle( $CIRCLE $TRIANGLE ) -|IsInTangent( $CIRCLE $CIRCLE ) -|IsOutTangent( $CIRCLE $CIRCLE ) -|PointOnCurve( $POINT $AXIS_CURVE ) -|And( $ASSERTION $ASSERTION ) -|Negation( $ASSERTION ) - -$POINT=[ POINT: A-Z ] -$CONICSECTION=[ CONICSECTION: a-zA-Z ] -$CIRCLE=[ CIRCLE: a-zA-Z ] -$NUMBER=[ NUMBER: number_generate ] -$EXPRESSION=[ EXPRESSION: expression_generate ] -$CURVE=[ CURVE: curve_generate ] -$POINTS=[ POINTS: POINT ] -|[ POINTS: ] # 多个点的集合 -$AXIS=[ AXIS: xAxis] -|[ AXIS: yAxis] -$AXIS_CURVE=[ AXIS_CURVE: AXIS] -|[ AXIS_CURVE: CURVE ] + +$ASSERTION=Coordinate ( $POINT ) equals ( $NUMBER , $NUMBER ) +|XCoordinate ( $POINT ) equals $NUMBER +|YCoordinate ( $POINT ) equals $NUMBER +|LocusEquation ( $POINT ) equals $EXPRESSION +|Locus ( $POINT ) equals $CURVE +|Quadrant ( $POINT ) equals $NUMBER +|Focus ( $CONICSECTION ) equals $POINT +|RightFocus ( $CONICSECTION ) equals $POINT +|LeftFocus ( $CONICSECTION ) equals $POINT +|LowerFocus ( $CONICSECTION ) equals $POINT +|UpperFocus ( $CONICSECTION ) equals $POINT +|FocalLength ( $CONICSECTION ) equals $NUMBER +|HalfFocalLength ( $CONICSECTION ) equals $NUMBER +|SymmetryAxis ( $CONICSECTION ) equals $AXIS +|Eccentricity ( $CONICSECTION ) equals $NUMBER +|Vertex ( $CONICSECTION ) equals $POINT +|UpperVertex ( $CONICSECTION ) equals $POINT +|LowerVertex ( $CONICSECTION ) equals $POINT +|LeftVertex ( $CONICSECTION ) equals $POINT +|RightVertex ( $CONICSECTION ) equals $POINT +|Directrix ( $CONICSECTION ) equals $LINE +|LeftDirectrix ( $CONICSECTION ) equals $LINE +|RightDirectrix ( $CONICSECTION ) equals $LINE +|MajorAxis ( $ELLIPSE ) equals $LINESEGMENT +|MinorAxis ( $ELLIPSE ) equals $LINESEGMENT +|RealAxis ( $ELLIPSE ) equals $LINESEGMENT +|ImaginaryAxis ( $ELLIPSE ) equals $LINESEGMENT +|LeftPart ( $HYPERBOLA ) equals $CURVE +|RightPart ( $HYPERBOLA ) equals $CURVE +|Asymptote ( $HYPERBOLA ) equals $LINE +|Diameter ( $CIRCLE ) equals $NUMBER +|Radius ( $CIRCLE ) equals $NUMBER +|Perimeter ( $CONICSECTION ) equals $NUMBER +|Center ( $CONICSECTION ) equals $POINT +|Expression ( $CURVE ) equals $EXPRESSION +|LineOf ( $POINT , $POINT ) equals $LINE +|Slope ( $LINE ) equals $NUMBER +|Inclination ( $LINE ) equals $NUMBER +|Intercept ( $LINE , $AXIS ) equals $NUMBER +|LineSegmentOf ( $POINT , $POINT ) equals $LINESEGMENT +|Length ( $LINESEGMENT ) equals $NUMBER +|MidPoint ( $LINESEGMENT ) equals $POINT +|OverlappingLine ( $LINESEGMENT ) equals $LINE +|PerpendicularBisector ( $LINESEGMENT ) equals $LINE +|Endpoint ( $LINESEGMENT ) equals $POINT +|Projection ( $POINT , $LINE ) equals $POINT +|InterceptChord ( $LINE , $CONICSECTION ) equals $LINESEGMENT +|TriangleOf ( $POINT , $POINT , $POINT ) equals $TRIANGLE +|IsInscribedCircle ( $CIRCLE , $TRIANGLE ) equals $BOOL +|CircumCircle ( $TRIANGLE ) equals $CIRCLE +|Incenter ( $TRIANGLE ) equals $POINT +|Orthocenter ( $TRIANGLE ) equals $POINT +|Circumcenter ( $TRIANGLE ) equals $POINT +|AngleOf ( $POINT , $POINT , $POINT ) equals $DEGREE +|VectorOf ( $POINT , $POINT ) equals $VECTOR +|DotProduct ( $VECTOR , $VECTOR ) equals $NUMBER +|NumIntersection ( $CURVE , $CURVE ) equals $NUMBER +|Intersection ( $CURVE , $CURVE ) equals $POINT +|FootPoint ( $LINE , $LINE ) equals $POINT +|Distance ( $POINT , $POINT ) equals $NUMBER +|Area ( $CONICSECTION ) equals $NUMBER +|TangentPoint ( $LINE , $CIRCLE ) equals $POINT +|TangentOfPoint ( $POINT , $CURVE ) equals $LINE +|TangentOnPoint ( $POINT , $CURVE ) equals $LINE +|Abs ( $LINESEGMENT ) equals $NUMBER +|lg ( $NUMBER ) equals $NUMBER +|InterReciprocal ( $NUMBER ) equals $NUMBER +|sqrt ( $NUMBER ) equals $NUMBER +|Max ( $NUMBER ) equals $NUMBER +|Min ( $NUMBER ) equals $NUMBER +|ApplyUnit ( $NUMBER , $DEGREESTR ) +|Between ( $POINT , $POINT , $POINT ) equals $BOOL +|IsIntersect ( $CURVE , $CURVE ) equals $BOOL +|IsPerpendicular ( $LINE , $LINE ) equals $BOOL +|IsParallel ( $LINE , $LINE ) equals $BOOL +|IsDiameter ( $LINESEGMENT , $CIRCLE ) equals $BOOL +|IsChordOf ( $LINESEGMENT , $CONICSECTION ) equals $BOOL +|IsTangent ( $LINE , $CONICSECTION ) equals $BOOL +|IsInscribedCircle ( $CIRCLE , $TRIANGLE ) equals $BOOL +|IsCircumCircle ( $CIRCLE , $TRIANGLE ) equals $BOOL +|IsInTangent ( $CIRCLE , $CIRCLE ) equals $BOOL +|IsOutTangent ( $CIRCLE , $CIRCLE ) equals $BOOL +|PointOnCurve ( $POINT , $CURVE ) equals $BOOL +|And ( $ASSERTION , $ASSERTION ) equals $BOOL +|Negation ( $ASSERTION ) equals $BOOL + +$POINT=POINT: capital_generate +|Center ( $CONICSECTION ) +|UpperVertex ( $CONICSECTION ) +|Projection ( $POINT , $LINE ) +|UpperFocus ( $CONICSECTION ) +|Incenter ( $TRIANGLE ) +|LeftFocus ( $CONICSECTION ) +|Orthocenter ( $TRIANGLE ) +|MidPoint ( $LINESEGMENT ) +|Circumcenter ( $TRIANGLE ) +|LowerVertex ( $CONICSECTION ) +|FootPoint ( $LINE , $LINE ) +|RightVertex ( $CONICSECTION ) +|RightFocus ( $CONICSECTION ) +|LeftVertex ( $CONICSECTION ) +|LowerFocus ( $CONICSECTION ) + +$NUMBER=NUMBER: number_generate +|Inclination ( $LINE ) +|lg ( $NUMBER ) +|Diameter ( $CIRCLE ) +|HalfFocalLength ( $CONICSECTION ) +|Min ( $NUMBER ) +|Quadrant ( $POINT ) +|InterReciprocal ( $NUMBER ) +|XCoordinate ( $POINT ) +|Radius ( $CIRCLE ) +|NumIntersection ( $CURVE , $CURVE ) +|Eccentricity ( $CONICSECTION ) +|Area ( $CONICSECTION ) +|YCoordinate ( $POINT ) +|Length ( $LINESEGMENT ) +|FocalLength ( $CONICSECTION ) +|Slope ( $LINE ) +|Perimeter ( $CONICSECTION ) +|Abs ( $LINESEGMENT ) +|Intercept ( $LINE , $AXIS ) +|DotProduct ( $VECTOR , $VECTOR ) +|Distance ( $POINT , $POINT ) +|sqrt ( $NUMBER ) + +$EXPRESSION=EXPRESSION: expression_generate +|Expression ( $CURVE ) +|LocusEquation ( $POINT ) + +$CURVE=CURVE: capital_generate +|RightPart ( $HYPERBOLA ) +|LeftPart ( $HYPERBOLA ) +|Locus ( $POINT ) + +$CONICSECTION=CONICSECTION: capital_generate + +$AXIS=AXIS: xAxis +|AXIS: yAxis +|SymmetryAxis ( $CONICSECTION ) + +$LINE=LINE: capital_generate +|OverlappingLine ( $LINESEGMENT ) +|RightDirectrix ( $CONICSECTION ) +|PerpendicularBisector ( $LINESEGMENT ) +|TangentOnPoint ( $POINT , $CURVE ) +|LineOf ( $POINT , $POINT ) +|LeftDirectrix ( $CONICSECTION ) +|TangentOfPoint ( $POINT , $CURVE ) + +$ELLIPSE=ELLIPSE: capital_generate + +$LINESEGMENT=LINESEGMENT: capital_generate +|ImaginaryAxis ( $ELLIPSE ) +|MinorAxis ( $ELLIPSE ) +|MajorAxis ( $ELLIPSE ) +|LineSegmentOf ( $POINT , $POINT ) +|RealAxis ( $ELLIPSE ) +|InterceptChord ( $LINE , $CONICSECTION ) + +$HYPERBOLA=HYPERBOLA: capital_generate + +$CIRCLE=CIRCLE: capital_generate +|CircumCircle ( $TRIANGLE ) + +$TRIANGLE=TRIANGLE: capital_generate +|TriangleOf ( $POINT , $POINT , $POINT ) + +$BOOL=BOOL: True +|BOOL: False + +$DEGREE=AngleOf ( $POINT , $POINT , $POINT ) +|ApplyUnit ( $NUMBER , $DEGREESTR ) + +$VECTOR=VECTOR: capital_generate +|VectorOf ( $POINT , $POINT ) + +$DEGREESTR=DEGREESTR: degree