From 3fa7365713f522c996dbd8b85a885aca8dfdfced Mon Sep 17 00:00:00 2001 From: Jason N Date: Thu, 7 Dec 2023 09:54:43 +1100 Subject: [PATCH 1/2] Fix parser to allow par identifiers in var array initialisers Previously only var identifiers, or par literals were allowed --- Makefile.in | 1 + changelog.in | 7 ++++ gecode/flatzinc/parser.tab.cpp | 8 ++-- gecode/flatzinc/parser.yxx | 8 ++-- test/flatzinc/subtyping.cpp | 77 ++++++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 test/flatzinc/subtyping.cpp diff --git a/Makefile.in b/Makefile.in index 3240253f71..0fca3dd78c 100755 --- a/Makefile.in +++ b/Makefile.in @@ -1215,6 +1215,7 @@ FLATZINCTESTSRC0 = \ test/flatzinc/magicsq_5.cpp \ test/flatzinc/oss.cpp \ test/flatzinc/steiner_triples.cpp \ + test/flatzinc/subtyping.cpp \ test/flatzinc/timetabling.cpp \ test/flatzinc/trucking.cpp \ test/flatzinc/on_restart_complete.cpp \ diff --git a/changelog.in b/changelog.in index a678f1a323..30b745e215 100755 --- a/changelog.in +++ b/changelog.in @@ -69,6 +69,13 @@ Date: 2020-??-?? [DESCRIPTION] Let's see. +[ENTRY] +Module: flatzinc +What: bug +Rank: minor +[DESCRIPTION] +Allow par identifiers in var array initialisers. + [ENTRY] Module: flatzinc What: change diff --git a/gecode/flatzinc/parser.tab.cpp b/gecode/flatzinc/parser.tab.cpp index 31648dea20..7079b2a3e6 100644 --- a/gecode/flatzinc/parser.tab.cpp +++ b/gecode/flatzinc/parser.tab.cpp @@ -2906,7 +2906,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { SymbolEntry e; ParserState* pp = static_cast(parm); - if (pp->symbols.get((yyvsp[0].sValue), e) && e.t == ST_INTVAR) + if (pp->symbols.get((yyvsp[0].sValue), e) && (e.t == ST_INTVAR || e.t == ST_INT)) (yyval.varSpec) = new IntVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type int " << (yyvsp[0].sValue) @@ -2986,7 +2986,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { SymbolEntry e; ParserState* pp = static_cast(parm); - if (pp->symbols.get((yyvsp[0].sValue), e) && e.t == ST_FLOATVAR) + if (pp->symbols.get((yyvsp[0].sValue), e) && (e.t == ST_FLOATVAR || e.t == ST_FLOAT)) (yyval.varSpec) = new FloatVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type float " << (yyvsp[0].sValue) @@ -3065,7 +3065,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { SymbolEntry e; ParserState* pp = static_cast(parm); - if (pp->symbols.get((yyvsp[0].sValue), e) && e.t == ST_BOOLVAR) + if (pp->symbols.get((yyvsp[0].sValue), e) && (e.t == ST_BOOLVAR || e.t == ST_BOOL)) (yyval.varSpec) = new BoolVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type bool " << (yyvsp[0].sValue) @@ -3144,7 +3144,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { ParserState* pp = static_cast(parm); SymbolEntry e; - if (pp->symbols.get((yyvsp[0].sValue), e) && e.t == ST_SETVAR) + if (pp->symbols.get((yyvsp[0].sValue), e) && (e.t == ST_SETVAR || e.t == ST_SET)) (yyval.varSpec) = new SetVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type set " << (yyvsp[0].sValue) diff --git a/gecode/flatzinc/parser.yxx b/gecode/flatzinc/parser.yxx index 365b2b6f86..1ce8017656 100755 --- a/gecode/flatzinc/parser.yxx +++ b/gecode/flatzinc/parser.yxx @@ -1327,7 +1327,7 @@ int_init : { SymbolEntry e; ParserState* pp = static_cast(parm); - if (pp->symbols.get($1, e) && e.t == ST_INTVAR) + if (pp->symbols.get($1, e) && (e.t == ST_INTVAR || e.t == ST_INT)) $$ = new IntVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type int " << $1 @@ -1384,7 +1384,7 @@ float_init : { SymbolEntry e; ParserState* pp = static_cast(parm); - if (pp->symbols.get($1, e) && e.t == ST_FLOATVAR) + if (pp->symbols.get($1, e) && (e.t == ST_FLOATVAR || e.t == ST_FLOAT)) $$ = new FloatVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type float " << $1 @@ -1439,7 +1439,7 @@ bool_init : { SymbolEntry e; ParserState* pp = static_cast(parm); - if (pp->symbols.get($1, e) && e.t == ST_BOOLVAR) + if (pp->symbols.get($1, e) && (e.t == ST_BOOLVAR || e.t == ST_BOOL)) $$ = new BoolVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type bool " << $1 @@ -1492,7 +1492,7 @@ set_init : { ParserState* pp = static_cast(parm); SymbolEntry e; - if (pp->symbols.get($1, e) && e.t == ST_SETVAR) + if (pp->symbols.get($1, e) && (e.t == ST_SETVAR || e.t == ST_SET)) $$ = new SetVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type set " << $1 diff --git a/test/flatzinc/subtyping.cpp b/test/flatzinc/subtyping.cpp new file mode 100644 index 0000000000..1cd72e3d54 --- /dev/null +++ b/test/flatzinc/subtyping.cpp @@ -0,0 +1,77 @@ +/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* + * Main authors: + * Jason Nguyen + * + * Copyright: + * Jason nguyen, 2023 + * + * This file is part of Gecode, the generic constraint + * development environment: + * http://www.gecode.org + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "test/flatzinc.hh" + +namespace Test { namespace FlatZinc { + + namespace { + /// Helper class to create and register tests + class Create { + public: + + /// Perform creation and registration + Create(void) { + (void) new FlatZincTest("subtyping::1", +R"FZN( +bool: pb = true; +int: pi = 1; +float: pf = 1.5; +set of int: ps = {1, 3}; +var bool: vb :: output_var; +var 1..1: vi :: output_var; +var 1.5..1.5: vf :: output_var; +var set of 1..1: vs :: output_var; +array [1..3] of var bool: vba = [vb, pb, true]; +array [1..3] of var int: via = [vi, pi, 3]; +array [1..3] of var float: vfa = [vf, pf, 3.5]; +array [1..3] of var set of int: vsa = [vs, ps, {1}]; +constraint bool_eq(vb, pb); +constraint set_card(vs, pi); +solve satisfy; +)FZN", +R"OUT(vb = true; +vf = 1.5; +vi = 1; +vs = 1..1; +---------- +)OUT"); + } + }; + + Create c; + } + +}} + +// STATISTICS: test-flatzinc From 4ea63ab01c44f4024467502fca96835fc3048696 Mon Sep 17 00:00:00 2001 From: Jason N Date: Fri, 8 Dec 2023 13:15:08 +1100 Subject: [PATCH 2/2] Add missing check for if restart_data was initialised --- gecode/flatzinc.hh | 1 + gecode/flatzinc/flatzinc.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gecode/flatzinc.hh b/gecode/flatzinc.hh index cf2f281d89..6f2741a253 100755 --- a/gecode/flatzinc.hh +++ b/gecode/flatzinc.hh @@ -529,6 +529,7 @@ namespace Gecode { namespace FlatZinc { object(new OnRestartData()); } } + bool initialized() const { return object() != nullptr; } OnRestartData& operator ()() { return *static_cast(object()); }; diff --git a/gecode/flatzinc/flatzinc.cpp b/gecode/flatzinc/flatzinc.cpp index 7cebce28d7..e90ec61bf4 100644 --- a/gecode/flatzinc/flatzinc.cpp +++ b/gecode/flatzinc/flatzinc.cpp @@ -2010,7 +2010,7 @@ namespace Gecode { namespace FlatZinc { bool FlatZincSpace::slave(const MetaInfo& mi) { if (mi.type() == MetaInfo::RESTART) { - if (restart_data().mark_complete) { + if (restart_data.initialized() && restart_data().mark_complete) { // Fail the space this->fail(); // Return true to signal we are in the global search space