是否有一种支持以下概念的语言,或者是否有一种模式可以实现与现有概念类似的东西?
概念
我想定义一个Rectangle
,其中包含以下属性:Length
,Height
,Area
,Perimeter
;其中Area = Length * Height
和Perimeter = (2 * Length) + (2 * Height)
。
鉴于上述说法,如果我想通过给Rectangle
和Length
创建Height
,它当然应该自动填写剩余的属性。< / p>
但是,它应该更进一步,并自动允许您创建具有任何两个属性的Rectangle
(例如Height
和Perimeter
),因为这在数学上也足以创建相同的Rectangle
{1}}。
示例
为了帮助解释这个想法,请举个例子:
//Declaration
Rectangle
{
Height, Length, Area, Perimeter;
Area = Height * Length;
Perimeter = (2 * Length) + (2 * Height);
}
//Usage
main()
{
var rectangleA = new Rectangle(Height, Length);
var rectangleB = new Rectangle(Height, Area);
Assert(rectangleA == rectangleB);
}
请注意我并不需要为
Rectangle
定义构造函数。请注意,如果使用Rectangle
和Height
创建Area
,则无需指定所需的特定逻辑。
编辑:对于正确的示例,应该是矩形而不是正方形。
答案 0 :(得分:6)
您正在寻找的是具有集成计算机代数系统的语言。它必须能够解决关于不同变量的方程式。
虽然有可能实现这样的东西,但我怀疑它是否有意义,因为在许多情况下,将无法解决方案或多种解决方案。
如果仅给出区域和周长,即使您的简单示例也不起作用,因为通常会有两个解决方案。 (我假设你的类实际上代表一个矩形而不是一个正方形,否则你不应该有长度和高度的单独变量。)
示例:
Input: area = 2, perimeter = 6
Solution 1: length = 2, height = 1
Solution 2: length = 1, height = 2
另一个与您的问题无关的评论:您的类显然包含冗余成员变量。由于各种原因,这是一件坏事,最重要的是可能出现不一致。除非你有 非常 严格的性能限制,否则你应该只存储其中的两个,比如长度和宽度,并提供在需要时计算其他的方法。
答案 1 :(得分:3)
当然存在这样的语言。很多人都这样做,正如你现在在自己对这个答案的评论中指出的那样。
在下面的示例中,我将使用Powerloom表示系统,该系统以名为STELLA的语言实现。 您可以在Common Lisp环境中使用它。 安装好所有内容后,您可以通过运行以下命令加载语言:
(cl:load "load-powerloom.lisp")
(in-package "STELLA")
(in-dialect "KIF")
这就是你开始构建令人敬畏的几何对象所需要的一切。
在STELLA中,您可以使用基元defconcept
定义一个概念:
(defconcept Rectangle (?r)
:documentation "Curious geometrical objects that live on a plane.")
使用deffunction
定义其属性:
(deffunction rect-height ((?t Rectangle)) :-> (?n INTEGER))
(deffunction rect-length ((?t Rectangle)) :-> (?n INTEGER))
(deffunction area ((?t Rectangle)) :-> (?n INTEGER))
(deffunction perimeter ((?t Rectangle)) :-> (?n INTEGER))
要制作区域,周长和矩形边之间的关系,您必须做出一些断言。这就是你assert
的目的。
(assert (forall (?t Rectangle)
(= (area ?t) (* (rect-height ?t) (rect-length ?t)))))
(assert (forall (?t Rectangle)
(= (perimeter ?t) (+ (* 2 (rect-height ?t))
(* 2 (rect-length ?t))))))
你告诉STELLA,对于所有矩形,该区域是高度和长度的乘积,对于所有矩形,周长是高度的两倍加上两倍长度。
现在你可以实例化你的对象,只要它们有意义,你给它的属性并不重要。
(definstance rect1 :Rectangle true :rect-height 10 :rect-length 10)
(definstance rect2 :Rectangle true :area 40 :rect-height 20)
在这里,您将rect1
实例化为高度和长度作为参数,rect2
为面积和高度。
但是检查语言是否符合您的预期总是好的:
STELLA> (retrieve all ?x (= (area rect1) ?x))
There is 1 solution:
#1: ?X=100
STELLA> (retrieve all ?x (= (rect-length rect2) ?x))
There is 1 solution:
#1: ?X=2
如果你厌倦了长方形并决定建造一个美丽的广场,为什么不推出一个概念?
(defconcept Square ((?r Rectangle))
:documentation "Weird rectangles that fascinated the Greeks"
:<=> (= (rect-height ?r) (rect-length ?r)))
简单地告诉STELLA,正方形是高度和长度相等的矩形。
现在尝试一下:
STELLA> (definstance nice-rectangle :Rectangle true :rect-length 10 :area 100)
|i|NICE-RECTANGLE
STELLA> (ask (Square nice-rectangle))
TRUE
我根本不是专家,但我发现这种语言非常吸引人。令人遗憾的是,互联网上关于它的信息很少。甚至手册都不完整。 有关详细信息,我建议从these slides开始。
着名的书籍SICP教导如何为这种语言建立一个不确定的评估者here. 最后,可以看到一篇精彩的文章,描述这些想法背后的动机和应用here。
答案 2 :(得分:2)
在C#中,您可以使用具有隐式getter和setter的属性。这样你就可以写出类似的东西:
public class Square {
public int Length {
get { return length; }
set { length = value; }
}
public int Area {
get { return length * length; }
set { length = Math.Sqrt(value); }
}
public int Perimeter {
get { return length * 4; }
set { length = value / 4; }
}
private int length;
}
现在你可以写:
Square square = new Square();
square.Length = 2;
Console.WriteLine(square.Length); // "2"
Console.WriteLine(square.Area); // "4"
Console.WriteLine(square.Perimeter); // "8"
square.Area = 9;
Console.WriteLine(square.Length); // "3"
Console.WriteLine(square.Area); // "9"
Console.WriteLine(square.Perimeter); // "12"
修改强>
C#还允许您在实例化对象时根据您的选择命名属性:
Square square1 = new Square { Perimeter = 12 };
Square square2 = new Square { Length = 4 };
答案 3 :(得分:2)
我不认为这样的事情确实以编程语言的形式存在。
然而,我能想到的第一种方法是定义一个Ontology,我指的是一套关于
的规则现在给出一个属性列表和所需的输出实体
我有
height
和width
,我需要Rectangle
系统可以通过规则图搜索路径,以根据提供的输入产生所需的结果。
Wolfram Alpha可能遵循上述技术