让我们定义两种助手类型:
lab_tickets_df.drop(columns = ["0"])
然后还有两个依赖于Inductive AB : Set := A | B.
Inductive XY : Set := X | Y.
和XY
的类型
AB
请注意Inductive Wrapped : AB -> XY -> Set :=
| W : forall (ab : AB) (xy : XY), Wrapped ab xy
| WW : forall (ab : AB), Wrapped ab (match ab with A => X | B => Y end)
.
Inductive Wrapper : XY -> Set :=
WrapW : forall (xy : XY), Wrapped A xy -> Wrapper xy.
构造函数–它只能是类型WW
和Wrapped A X
的值。
现在我想在Wrapped B Y
上进行图案匹配:
Wrapper Y
但出现错误
Definition test (wr : Wrapper Y): nat :=
match wr with
| WrapW Y w =>
match w with
| W A Y => 27
end
end.
为什么会发生? Error: Non exhaustive pattern-matching: no clause found for pattern WW _
强制包含Wrapper
的版本为Wrapped
,类型签名强制A
和Y
的构造函数禁止为WW
和A
同时。我不明白为什么还要考虑这种情况,但我不得不检查这似乎是不可能的。
如何解决这种情况?
答案 0 :(得分:3)
让我们简化一下:
Inductive MyTy : Set -> Type :=
MkMyTy : forall (A : Set), A -> MyTy A.
Definition extract (m : MyTy nat) : nat :=
match m with MkMyTy _ x => S x end.
此操作失败:
The term "x" has type "S" while it is expected to have type "nat".
浪费。
这是因为我说
Inductive MyTy : Set -> Type
与参数相反,这使MyTy
的第一个参数的索引为MyTy
。带有参数的归纳类型可能看起来像这样:
Inductive list (A : Type) : Type :=
| nil : list A
| cons : A -> list A -> list A.
参数在:
的左侧命名,而不是每个构造函数的定义中的forall
-d。 (它们仍然存在于定义之外的构造函数类型中:cons : forall (A : Type), A -> list A -> list A
。)如果我将Set
设为MyTy
的参数,则可以定义extract
:
Inductive MyTy (A : Set) : Type :=
MkMyTy : A -> MyTy A.
Definition extract (m : MyTy nat) : nat :=
match m with MkMyTy _ x => S x end.
这样做的原因是,在内部,match
忽略您从外部就知道的有关scrutinee索引的任何信息。 (或者,相反,Gallina中的基础match
表达式会忽略索引。当您在源代码中编写match
时,Coq会尝试将其转换为原始形式,同时并入来自索引的信息,但是它通常会失败。)m : MyTy nat
的第一个版本中的extract
根本无关紧要。相反,根据构造函数S : Set
,匹配项给了我x : S
(名称由Coq自动选择)和MkMyTy
,而没有提到nat
。同时,因为MyTy
在第二个版本中有一个参数,所以我实际上得到了x : nat
。 _
这次确实是一个占位符;强制将其写为_
,因为没有匹配项,您可以Set Asymmetric Patterns
使其消失。
我们区分参数和索引的原因是因为参数有很多限制-最值得注意的是,如果I
是带有参数的归纳类型,则参数必须在每个构造函数的返回类型中作为变量出现:
Inductive F (A : Set) : Set := MkF : list A -> F (list A).
(* ^--------^ BAD: must appear as F A *)
在您遇到的问题中,我们应该尽可能地设置参数。例如。 match wr with Wrap Y w => _ end
位是错误的,因为XY
的{{1}}参数是一个索引,因此Wrapper
的事实将被忽略;您也需要处理wr : Wrapper Y
情况。 Coq并没有告诉你。
Wrap X w
现在您的Inductive Wrapped (ab : AB) : XY -> Set :=
| W : forall (xy : XY), Wrapped ab xy
| WW : Wrapped ab (match ab with A => X | B => Y end).
Inductive Wrapper (xy : XY) : Set := WrapW : Wrapped A xy -> Wrapper xy.
会(几乎)进行编译:
test
因为具有参数可以为Coq提供Definition test (wr : Wrapper Y): nat :=
match wr with
| WrapW _ w => (* mandatory _ *)
match w with
| W _ Y => 27 (* mandatory _ *)
end
end.
详尽的信息,以便使用match
索引中的信息。如果您发出Wrapped
,您会发现有一些跳跃会通过原始Print test.
传递有关索引Y
的信息,否则它们将被忽略。 See the reference manual for more information.
答案 1 :(得分:2)
该解决方案虽然简单却棘手:
import java.sql.Timestamp
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.spark.sql.SparkSession
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe
import org.apache.spark.streaming.kafka010.KafkaUtils
import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent
import java.time.{LocalDate, LocalDateTime}
import java.util.Calendar
object SparkKafka {
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("test_app")
.getOrCreate()
val sparkContext = spark.sparkContext
val ssc = new StreamingContext(sparkContext, Seconds(1)) // the polling frequency is 2 seconds, can be modified based on the BM requirements.
///val currentHour = now.get(Calendar.HOUR_OF_DAY)
log.info("Before starting the Stream -->>")
val stream = KafkaUtils.createDirectStream[String, String](ssc, PreferConsistent, Subscribe[String, String]
(Array.apply("Kafka_topic_name"), getKafkaParams()))
.map(record => record.value)
stream.foreachRDD { rdd =>
try {
if (!rdd.isEmpty()) {
log.info("rdd is not empty and saving to -->>"+LocalDate.now.getYear+"/"+LocalDate.now.getMonth+"/"+LocalDate.now.getDayOfMonth+"/"+LocalDateTime.now().getHour)
rdd.saveAsTextFile("hdfs:///<folder to save>") //TODO::: Externalize the HDFS location to Props
LocalDate.now.getMonth
if (null != args && null != args {
0
} && args {
0
}.equals("log")) {
rdd.foreach(x => print("Message read and saved TO S3 bucket----*****--->>" + x))
}
}
} catch {
case t: Throwable =>
t.printStackTrace() // TODO: handle error)
log.error("Exception occured while processing the data exception is {}", t.getCause)
}
}
ssc.start()
log.info("started now-->> " + compat.Platform.currentTime)
ssc.awaitTermination()
}
def getKafkaParams(): Map[String, Object] = {
Map[String, Object]("bootstrap.servers" -> "host:port
"key.deserializer" -> classOf[StringDeserializer],
"value.deserializer" -> classOf[StringDeserializer],
"group.id" -> "Group_Name",
// "sasl.kerberos.service.name" -> "kafka",
"auto.offset.reset" -> "latest",
"enable.auto.commit" -> (true: java.lang.Boolean))
}
}
问题在于,Coq并未推断出某些必要的不变式以意识到Definition test (wr : Wrapper Y): nat.
refine (match wr with
| WrapW Y w =>
match w in Wrapped ab xy return ab = A -> xy = Y -> nat with
| W A Y => fun _ _ => 27
| _ => fun _ _ => _
end eq_refl eq_refl
end);
[ | |destruct a]; congruence.
Defined.
情况是荒谬的。我必须明确为其提供证明。
在此解决方案中,我更改了WW
以返回一个函数,该函数需要两个证明并将其带到我们实际结果的上下文中:
match
显然是ab
A
显然是xy
我已经涵盖了忽略这些假设的真实案例,并且我推迟了“坏”案例,这些案例后来被证明是错误的,后来变得微不足道。我被迫手动通过了Y
,但它确实有效,而且看起来还不错。