Skip to content

Commit 2fabbd2

Browse files
authored
[DUCK] 限制低粒度与高粒度结合 (#260)
- maxGrain 补充在更多predicate中的实现 - intersect 增加 maxGrain 考量
1 parent 25a2a69 commit 2fabbd2

File tree

6 files changed

+33
-20
lines changed

6 files changed

+33
-20
lines changed

duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/Rules.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,10 @@ trait Rules extends DimRules {
213213
if td1.timeGrain > td2.timeGrain && !(td1.hint == Hint.Date && td2.hint == Hint.Date) ||
214214
// 上午的8-9点
215215
td1.timeGrain == td2.timeGrain && td1.timeGrain == Hour && isAPartOfDay(t1) && !isAPartOfDay(t2) =>
216-
intersectToken(options, td1, td2)
216+
val g1 = td1.timePred.maxGrain
217+
val g2 = td2.timePred.maxGrain
218+
if (g1.isDefined && g2.isDefined && g1.get < g2.get) None
219+
else intersectToken(options, td1, td2)
217220
}
218221
)
219222

duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/Time.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ case class TimeData(timePred: TimePredicate,
208208
case TimeDatePredicate(second, minute, hour, _, _, dayOfMonth, month, year, _) =>
209209
// 如:2021年10月1日12点三十分
210210
Simple(year, month, dayOfMonth, hour, minute, second, offset=Some(false))
211-
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, _, _, _, _), IntersectTimePredicate(TimeDatePredicate(_, _, _, _, _, dayOfMonth, month, _, _), SeriesPredicate(_))) =>
211+
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, _, _, _, _), IntersectTimePredicate(TimeDatePredicate(_, _, _, _, _, dayOfMonth, month, _, _), SeriesPredicate(_, _))) =>
212212
// 如: 明年三月一号十二点三十分, 年份隐式表达SeriesPredicate
213213
Simple(None, month, dayOfMonth, hour, minute, second, offset=Some(true))
214214
case IntersectTimePredicate(SequencePredicate(_), TimeDatePredicate(_, _, _, _, _, _, _, year, _)) =>
@@ -217,26 +217,26 @@ case class TimeData(timePred: TimePredicate,
217217
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, _, _, _, _), SequencePredicate(_)) =>
218218
// 如:除夕十二点三十分,没有年份表达,除夕SequencePredicate
219219
Simple(hour=hour, minute=minute, second=second, offset=Some(false))
220-
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, _, _, _, _), IntersectTimePredicate(SequencePredicate(_), SeriesPredicate(_))) =>
220+
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, _, _, _, _), IntersectTimePredicate(SequencePredicate(_), SeriesPredicate(_, _))) =>
221221
// 如:今年除夕十二点三十分,年份隐式表达,除夕SequencePredicate
222222
Simple(hour=hour, minute=minute, second=second, offset=Some(true))
223223
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, _, _, _, _), IntersectTimePredicate(_, TimeDatePredicate(_, _, _, _, _, _, _, year, _))) =>
224224
// 如:2021年[除夕、节气、西方节日]十二点三十分,有具体年份表达
225225
Simple(year=year, hour=hour, minute=minute, second=second, offset=Some(false))
226-
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, _, _, _, _), IntersectTimePredicate(SeriesPredicate(_), SeriesPredicate(_))) =>
226+
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, _, _, _, _), IntersectTimePredicate(SeriesPredicate(_, _), SeriesPredicate(_, _))) =>
227227
// 如:明年[清明节、西方节日]十二点三十分,年份隐式表达,节气SeriesPredicate
228228
Simple(hour=hour, minute=minute, second=second, offset=Some(true))
229-
case IntersectTimePredicate(SeriesPredicate(_), TimeDatePredicate(second, minute, hour, _, _, _, _, year, _)) =>
229+
case IntersectTimePredicate(SeriesPredicate(_, _), TimeDatePredicate(second, minute, hour, _, _, _, _, year, _)) =>
230230
// 如:2021年[清明节、西方节日],节气需要根据年份查表获取具体日期,只抽取年,节气SeriesPredicate
231231
Simple(year=year, hour=hour, minute=minute, second=second, offset=Some(false))
232-
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, dayOfMonth, month, _, _), SeriesPredicate(_)) =>
232+
case IntersectTimePredicate(TimeDatePredicate(second, minute, hour, _, _, dayOfMonth, month, _, _), SeriesPredicate(_, grain)) =>
233233
// 如:[清明节、西方节日]十二点三十分,今年国庆节,明年中秋节,今天十二点三十分,年份/日期隐式表达和节气SeriesPredicate
234234
val offset = (second.isDefined || minute.isDefined || hour.isDefined) && holiday.exists(_.nonEmpty)
235235
Simple(None, month, dayOfMonth, hour, minute, second, offset=Some(!offset))
236-
case IntersectTimePredicate(SeriesPredicate(_), SeriesPredicate(_)) =>
236+
case IntersectTimePredicate(SeriesPredicate(_, _), SeriesPredicate(_, _)) =>
237237
// 如:今年[清明节、西方节日],年份隐式表达和节气SeriesPredicate
238238
Simple(offset=Some(true))
239-
case SeriesPredicate(_) =>
239+
case SeriesPredicate(_, _) =>
240240
// 如:[清明节、西方节日]西方节日和节气SeriesPredicate
241241
Simple(offset=if (holiday.exists(_.nonEmpty)) Some(false) else Some(true))
242242
case _ => Simple()

duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/helper/TimePredicateHelpers.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ object TimePredicateHelpers {
145145
}
146146
}
147147

148-
SeriesPredicate(timeSeqMap(false, f, basePred))
148+
SeriesPredicate(timeSeqMap(false, f, basePred), basePred.maxGrain)
149149
}
150150

151151
def timeCycle(grain: Grain): CycleSeriesPredicate = timeCycle(grain, grain)
@@ -192,7 +192,7 @@ object TimePredicateHelpers {
192192
}
193193
}
194194

195-
SeriesPredicate(series)
195+
SeriesPredicate(series, cycleSP.maxGrain)
196196
}
197197

198198
/**
@@ -221,7 +221,7 @@ object TimePredicateHelpers {
221221
else (Stream(nth), Stream.empty)
222222
}
223223
}
224-
SeriesPredicate(series)
224+
SeriesPredicate(series, f.maxGrain)
225225
}
226226

227227
/**
@@ -255,7 +255,7 @@ object TimePredicateHelpers {
255255
(Stream.iterate(anchor)(f(-1)).tail, Stream.iterate(anchor)(f(1)))
256256
}
257257
}
258-
SeriesPredicate(series)
258+
SeriesPredicate(series, Some(Day))
259259
}
260260

261261
/**

duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/package.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ package object time {
144144
def runPredicate(tp: TimePredicate): SeriesPredicateF = {
145145
tp match {
146146
case EmptyTimePredicate => EmptySeriesPredicate
147-
case SeriesPredicate(f) => f
147+
case SeriesPredicate(f, _) => f
148148
case TimeDatePredicate(sec, min, hour, ampm, dayOfWeek, dayOfMonth, month, year, calendar) =>
149149
if (hour.isEmpty && ampm.nonEmpty) EmptySeriesPredicate
150150
else {
@@ -197,8 +197,8 @@ package object time {
197197
t2 <- resolveTimeData(t, td2)
198198
} yield {
199199
val to =
200-
if (td2.timePred.maxGrain.nonEmpty && td1.timeGrain > td2.timePred.maxGrain.get) {
201-
copyGrain(Year, td2.timePred.maxGrain.get, t1, t2)
200+
if (td2.timePred.maxGrain.nonEmpty && td1.timeGrain > td2.timePred.maxGrain.get && td1.timeGrain.finer().isDefined) {
201+
copyGrain(Year, td1.timeGrain.finer().get, t1, t2)
202202
} else {
203203
(td1.timeGrain, td2.timeGrain) match {
204204
case (Year, Month) => t2.copy(start = t2.start.withYear(t1.start.year))

duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/predicates.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ object predicates {
7373
}
7474
}
7575

76-
case class SeriesPredicate(f: SeriesPredicateF) extends TimePredicate {
76+
case class SeriesPredicate(f: SeriesPredicateF, grainOpt: Option[Grain]) extends TimePredicate {
7777
override def toString: String = "f:Series"
78+
override val maxGrain: Option[Grain] = grainOpt
7879
}
7980

8081
case class IntersectTimePredicate(pred1: TimePredicate, pred2: TimePredicate)
@@ -105,12 +106,17 @@ object predicates {
105106
/**
106107
* 用td1的部分信息替换td2的结果,解决明年的今天、上个月的今天之类的问题
107108
*/
108-
case class ReplacePartPredicate(td1: TimeData, td2: TimeData) extends TimePredicate
109+
case class ReplacePartPredicate(td1: TimeData, td2: TimeData) extends TimePredicate {
110+
override val maxGrain: Option[Grain] = td1.timeGrain
111+
}
109112

110113
case object EndOfGrainPredicate extends TimePredicate
111114

112115
case class CycleSeriesPredicate(seriesF: SeriesPredicateF, n: Int, grain: Grain)
113-
extends TimePredicate
116+
extends TimePredicate {
117+
118+
override val maxGrain: Option[Grain] = Some(grain)
119+
}
114120

115121
val singleNumeber: Predicate = isIntegerBetween(0, 9)
116122

duckling-fork-chinese/core/src/test/scala/com/xiaomi/duckling/dimension/time/TimeTest.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,13 @@ class TimeTest extends UnitSpec {
139139
}
140140
}
141141

142-
it("fix #187") {
142+
it("不需要支持的") {
143143
val opt = options.copy(full = true, withLatent = false)
144-
val cases = Table("query", "国庆晚", "十月一晚", "下钟", "")
144+
val cases = Table("query",
145+
// fix #187
146+
"国庆晚", "十月一晚", "下钟", "",
147+
// fix #259
148+
"上午今天早上七点")
145149
forAll(cases) {query =>
146150
parse(query, options = opt) should be (empty)
147151
}

0 commit comments

Comments
 (0)