From b1bd213b10dd60bb8287ae3275747bc06141a6b9 Mon Sep 17 00:00:00 2001 From: ccamel Date: Sat, 23 Nov 2024 11:51:22 +0100 Subject: [PATCH] test(dict): add test cases for correct ordering of desugared terms --- engine/text_test.go | 104 ++++++++++++++++++++++++++++++++++++++++++++ interpreter_test.go | 28 ++++++++++++ 2 files changed, 132 insertions(+) diff --git a/engine/text_test.go b/engine/text_test.go index 1a0cedb..3ddd593 100644 --- a/engine/text_test.go +++ b/engine/text_test.go @@ -282,6 +282,58 @@ point(point{x: 5}.x). }, }, )}, + {title: "dict head (3)", text: ` +point(point{x: 5}.x) :- true. +`, result: buildOrderedMap( + procedurePair{ + Key: procedureIndicator{name: NewAtom("foo"), arity: 1}, + Value: &userDefined{ + multifile: true, + clauses: clauses{ + { + pi: procedureIndicator{name: NewAtom("foo"), arity: 1}, + raw: &compound{functor: NewAtom("foo"), args: []Term{NewAtom("c")}}, + bytecode: bytecode{ + {opcode: OpGetConst, operand: NewAtom("c")}, + {opcode: OpExit}, + }, + }, + }, + }, + }, + procedurePair{ + Key: procedureIndicator{name: NewAtom("point"), arity: 1}, + Value: &userDefined{ + clauses: clauses{ + { + pi: procedureIndicator{name: NewAtom("point"), arity: 1}, + raw: atomIf.Apply( + &compound{functor: "point", args: []Term{ + &compound{functor: "$dot", args: []Term{ + &dict{compound: compound{functor: "dict", args: []Term{NewAtom("point"), NewAtom("x"), Integer(5)}}}, + NewAtom("x"), + }}}}, + NewAtom("true")), + vars: []Variable{lastVariable() + 1}, + bytecode: bytecode{ + {opcode: OpGetVar, operand: Integer(0)}, + {opcode: OpEnter}, + {opcode: OpCall, operand: procedureIndicator{name: atomTrue, arity: 0}}, + {opcode: OpPutDict, operand: Integer(3)}, + {opcode: OpPutConst, operand: NewAtom("point")}, + {opcode: OpPutConst, operand: NewAtom("x")}, + {opcode: OpPutConst, operand: Integer(5)}, + {opcode: OpPop}, + {opcode: OpPutConst, operand: NewAtom("x")}, + {opcode: OpPutVar, operand: Integer(0)}, + {opcode: OpCall, operand: procedureIndicator{name: atomDot, arity: Integer(3)}}, + {opcode: OpExit}, + }, + }, + }, + }, + }, + )}, {title: "dict body", text: ` p :- foo(point{x: 5}). `, result: buildOrderedMap( @@ -328,6 +380,58 @@ p :- foo(point{x: 5}). }, }, )}, + {title: "dict body (2)", text: ` +x(X) :- p(P), =(X, P.x). +`, result: buildOrderedMap( + procedurePair{ + Key: procedureIndicator{name: NewAtom("foo"), arity: 1}, + Value: &userDefined{ + multifile: true, + clauses: clauses{ + { + pi: procedureIndicator{name: NewAtom("foo"), arity: 1}, + raw: &compound{functor: NewAtom("foo"), args: []Term{NewAtom("c")}}, + bytecode: bytecode{ + {opcode: OpGetConst, operand: NewAtom("c")}, + {opcode: OpExit}, + }, + }, + }, + }, + }, + procedurePair{ + Key: procedureIndicator{name: NewAtom("x"), arity: 1}, + Value: &userDefined{ + clauses: clauses{ + { + pi: procedureIndicator{name: NewAtom("x"), arity: 1}, + raw: atomIf.Apply( + NewAtom("x").Apply(lastVariable()+1), + seq( + atomComma, + NewAtom("p").Apply(lastVariable()+2), + atomEqual.Apply(lastVariable()+1, NewAtom("$dot").Apply(lastVariable()+2, NewAtom("x"))), + )), + vars: []Variable{lastVariable() + 1, lastVariable() + 2, lastVariable() + 3}, + bytecode: bytecode{ + {opcode: OpGetVar, operand: Integer(0)}, + {opcode: OpEnter}, + {opcode: OpPutVar, operand: Integer(1)}, + {opcode: OpCall, operand: procedureIndicator{name: NewAtom("p"), arity: 1}}, + {opcode: OpPutVar, operand: Integer(1)}, + {opcode: OpPutConst, operand: NewAtom("x")}, + {opcode: OpPutVar, operand: Integer(2)}, + {opcode: OpCall, operand: procedureIndicator{name: NewAtom("."), arity: 3}}, + {opcode: OpPutVar, operand: Integer(0)}, + {opcode: OpPutVar, operand: Integer(2)}, + {opcode: OpCall, operand: procedureIndicator{name: NewAtom("="), arity: 2}}, + {opcode: OpExit}, + }, + }, + }, + }, + }, + )}, {title: "dynamic", text: ` :- dynamic(foo/1). foo(a). diff --git a/interpreter_test.go b/interpreter_test.go index db01532..2cfd796 100644 --- a/interpreter_test.go +++ b/interpreter_test.go @@ -1022,6 +1022,27 @@ func TestDict(t *testing.T) { "X": "1", }}}, }, + { + program: "ok. p(point{x:1}.x) :- ok.", + query: "p(X).", + wantResult: []result{{solutions: map[string]TermString{ + "X": "1", + }}}, + }, + { + program: "point(point{x: X}.x) :- X = 5.", + query: "point(X).", + wantResult: []result{{solutions: map[string]TermString{ + "X": "5", + }}}, + }, + { + program: "point(point{x: 5}.X) :- X = x.", + query: "point(X).", + wantResult: []result{{solutions: map[string]TermString{ + "X": "5", + }}}, + }, // access { query: "A = point{x:1,y:2}.x.", @@ -1055,6 +1076,13 @@ func TestDict(t *testing.T) { "X": "10", }}}, }, + { + program: "p(P) :- P = point{x:10, y:20}. x(X) :- p(P), X = P.x.", + query: "x(X).", + wantResult: []result{{solutions: map[string]TermString{ + "X": "10", + }}}, + }, { query: "A = point{x:1,y:2}.z.", wantResult: []result{