头部和身体接地

时间:2019-03-28 21:47:17

标签: prolog

我正在使用SWI-Prolog编写软件,在该软件中,我必须查找谓词的所有基础。特别是假设我可以独立访问头部和身体,则所有将头部和相关身体固定的替换都可以。这是我要获取的行为的示例:

nsecureSkipVerify = true
defaultEntryPoints = ["https", "http"]

# WEB interface of Traefik - it will show web page with overview of frontend and backend configurations
[api]
  entryPoint = "traefik"
  dashboard = true
  address = ":8080"

# Force HTTPS
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

# Let's encrypt configuration
[acme]
email = "example@gmail.com" #any email id will work
storage="acme.json"
entryPoint = "https"
acmeLogging=true
onDemand = false #create certificate when container is created
[acme.dnsChallenge]
  provider = "cloudflare"
  delayBeforeCheck = 300
[[acme.domains]]
   main = "example.com"
[[acme.domains]]
   main = "*.example.com"

# Connection to docker host system (docker.sock)
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "example.com"
watch = true
# This will hide all docker containers that don't have explicitly
# set label to "enable"
exposedbydefault = false

也许可以概括为:

student(a).
student(b).
student(c).

play.

study(A):-
    play,
    student(A).

ground(Head,Body,Result):-
    % some code
    ...

?- ground([study(A)],[play, student(A)],R).
R = [
    [study(a):- play, student(a)],
    [study(b):- play, student(b)],
    [study(c):- play, student(c)]
]

因此,对于身体,找到所有非地面变量,将其接地,然后将头部变量接地。基本上找到所有组合。问题是要管理身体... 也许我可以使用例如dog(d). dog(e). study(A,B):- play, dog(B), student(A). ?- ground([study(A,B)],[play, dog(B),student(A)],R). R = [[study(a):- play, dog(d), student(a)] ... ] =../2functor/3,但是我不知道如何对身体(see this question/answer)进行拍针。

谢谢!

2 个答案:

答案 0 :(得分:2)

我不确定为什么在示例中您提供的目标位于列表内,而您也提供了正文。

此答案中的过程以目标为目标,获取匹配子句,然后获取所有解决方案(在途中绑定变量)。如果没有目标,则可能会使一些变量不受约束。回溯时,可能会使用其他与初始目标匹配的子句。

ground(Goal, Body, LGroundClauses):-
  clause(Goal, Body),
  findall((Goal:-Body), call(Body), LGroundClauses).

样品运行:

?- ground(study(A), Body, LClauses).
Body = (play, student(A)),
LClauses = [ 
  (study(a):-play, student(a)), 
  (study(b):-play, student(b)), 
  (study(c):-play, student(c))
] 

答案 1 :(得分:1)

请注意有关问题和已接受的解决方案的评论,此评论可能太长了。

@gusbro写道(重点是我的):“我不确定为什么在示例中您提供的目标位于列表内,同时还提供了正文。”我也希望在这一点上得到澄清。

ISO Prolog Core标准允许clause/2谓词检索 public 谓词的子句。但是大多数Prolog系统(特别是SWI-Prolog除外)仅允许使用clause/2访问动态谓词的子句。此外,可以将SWI-Prolog protect_static_code标志设置为true以在静态谓词上禁用clause/2。除非谓词被声明为动态,否则这将使解决方案不可移植(在部署方案中可能是不可取的)。假设Body参数确实绑定在ground(Head,Body,Result)目标中,一个可能的选择是使用目标列表 construct 子句主体。像这样:

ground(Goal, BodyGoals, LGroundClauses):-
    list_to_conjunction(BodyGoals, Body),
    findall(Goal:-Body, call(Body), LGroundClauses).

这将消除调用clause/2的要求,并可能使谓词具有动态性以实现可移植性。但这对您来说有意义吗?