2013-02-17 11 views
6

Próbuję zdefiniować predykat w linii, aby przekazać go do innego predykatu w Prologu.Definiowanie predykatu wewnątrz predykatu w prologu

% Test if a "product" of graphs G1 and G2 has a "mini-loop" starting from Q 
test_property_combined(G1,G2,Q):- 
    (g12(Q1,Q2) :- combine(G1,G2,Q1,Q2)), 
    some_property(g12,Q). 

(składnia powyżej jest oczywiście błędne.)

Później g12 będzie wywoływany przez call

% Test if a graph G has a "mini-loop" starting from Q 
some_property(G,Q):- 
    Goal1 =.. [G,Q,C], 
    Goal2 =.. [G,C,Q], 
    call(Goal1), 
    call(Goal2). 

problem nie zostanie rozwiązany, ponieważ chcę, aby przetestować some_property na jakiejś agregacja wcześniej zdefiniowanych predykatów.

% Create a "product" of graphs G1 and G2 
combine(G1,G2,(Q1,Q2),(Q3,Q4)):- 
    Goal1 =.. [G1,Q1,Q3], 
    Goal2 =.. [G2,Q2,Q4], 
    call(Goal1), 
    call(Goal2). 

Wymienione predykaty i przykładem zapytania testu:

% g1 and g2 are graphs 
g1(a,b). 
g1(b,a). 

g2(c,d). 
g2(d,c). 


?- test_property_combined(g1,g2,(a,c)). 

jaki sposób można go o to robi?

+0

Przepraszam, nie mogę zrozumieć. Czy wiesz o [lambda] (http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl)? – CapelliC

+0

Nie, ale wydaje się trochę przesadą, aby użyć go tutaj. Dzięki za link. –

+0

Nie używaj '(= ..)/2' do emulowania programowania wyższego rzędu. Zamiast tego użyj połączenia/N. Jest znacznie bardziej ogólny i pozwala na użycie ['library (lambda)'] (http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord) – false

Odpowiedz

2

Nie jestem pewny, aby uzyskać punkt, ale to działa:

test_property_combined(G1,G2,Q):- 
    assert((g12(Q1,Q2) :- combine(G1,G2,Q1,Q2))), 
    some_property(g12,Q). 

Ok, może być coś takiego

:- use_module(library(lambda)). 

test_property_combined(G1,G2,Q):- 
    % (g12(Q1,Q2) :- combine(G1,G2,Q1,Q2)), 
    Pred = \Z^T^combine(G1,G2,Z,T), 
    some_property(Pred,Q). 


combine(G1,G2,(Q1,Q2),(Q3,Q4)):- 
    Goal1 =.. [G1,Q1,Q3], 
    Goal2 =.. [G2,Q2,Q4], 
    call(Goal1), 
    call(Goal2). 


some_property(G,Q):- 
    call(G, Q, C), 
    call(G, C, Q). 

ostatniej edycji (mam nadzieję) z pełnym kodem:

test_property_combined(G1,G2,Q):- 
    some_property(combine(G1,G2),Q). 

combine(G1,G2,(Q1,Q2),(Q3,Q4)):- 
    call(G1,Q1,Q3), 
    call(G2,Q2,Q4). 

some_property(G,Q):- 
    call(G, Q, C), 
    call(G, C, Q). 

g1(a,b). 
g1(b,a). 

g2(c,d). 
g2(d,c). 

@false => użyteczne uwagi, jak zwykle!

+1

Nie zapomnij o sprzątaniu przez wycofanie predykatu temp. –

+1

Tak z ** retractall (g12 (__, __)) **. – joel76

+0

Dzięki, to działa. To faktycznie jest rozwodnioną wersją mojego rzeczywistego kodu, ale miałem nadzieję, że nadal będzie sensowne definiowanie predykatu w linii. –

Powiązane problemy