Hello Joachim, you are absolutely right. But I chose that small example just for illustration purposes. I will try to rephrase it in more illustrative terms. Say you have: cost(green, Size, Cost) :- Cost is Size*2. cost(black, Size, Cost) :- Cost is Size/2. Now you need to declare constraints on the Size related with objects: size(table, 10). size(chair, 5). ... but from another *totally independent* predicate you want to constraint the same variable Size, which could be, for instance, the second argument of another predicate: machine(a1, 10, ... ). machine(a2, 20, ... ). ... And even more, you have several independent constraints which refer to the Size variable and to another variables as well. I can easily think in a Prolog program which binds the Size variable to the same value in each constraint: some_rule :- size(Obj,S),..,machine(A,S),..,cost(Col,S,C). Or even: % some_rule(Color, Object, Size, Machine, Cost) some_rule(green, table, 10, a1, C) :- Cost is Size*2. some_rule(green, chair, 5, a1, C) :- Cost is Size*2. some_rule(black, table, 10, a1, C) :- Cost is Size/2. some_rule(black, chair, 5, a1, C) :- Cost is Size/2. some_rule(green, table, 10, a1, C) :- Cost is Size*2. some_rule(green, table, 10, a2, C) :- Cost is Size*2. ... Again this example could seem stupid, but imagine I have hundreds of variables from which I need to declare constraints just using *local* information, without taking care of other relations with all the other variables that only constraint that variable *indirectly*. In the end I also want to see what are the instantiations of all the involved variables. Speaking in more technical terms, the "execution" of a Prolog program can be viewed as the construction of a "model", in which if variable Size has been already instantiated, it should not take another value. Because it is cumbersome to put all variables as arguments (and also because not all models will require all the variables) one has the necessity of passing a "context" which includes the current "partial" model. One way to do that is to assert the value of a variable the first time it is required and, in subsequent steps, check if that variable has been previously instantiated. Eventually (when the first binding fails) we should backtrack and reassert the value to the next possible one, and so on...This approach is inefficient. An alternative way (the one I described in the other mail) is to maintain a list (with all variables which are being instantiated) which is passed as an argument to all the predicates, and modified during the execution flow. This requires a pre-compilation step to include the lists in all predicates. You can think in this option as the preprocessing step that Definite Clause Grammars use in the --> operator definition. I guess this problem is not related to the declarative meaning of a program. It is simply a problem that arises when dealing with big systems (high number of variables) with a lot of interdependencies between them. Mmm... sorry for this long email. I hope it is clearer now... Vicenç > Remember that you are using a logic programming language, and think about > the declarative meaning of your code. A predicate is something that is > true or false. So what is the meaning of cost(C)? It means > "cost(C) is true iff C is a cost" or in other words "C is a cost". > But the cost of what? You see it makes no sense declaratively. > > What you probably want it a predicate like cost(Color,Size,Cost), which > means "Cost is the cost of something with color Color and size Size", > and it could be defined as > > cost(green, Size, Cost) :- Cost is Size*2. > cost(black, Size, Cost) :- Cost is Size/2. > ... > > > -- JoachimReceived on Wed May 30 2007 - 17:04:48 CEST
This archive was generated by hypermail 2.3.0 : Wed Sep 25 2024 - 15:13:20 CEST